如何从概率条形图生成随机向量?

时间:2017-05-08 03:07:18

标签: python matlab frequency-distribution

我生成了一个条形图,用于计算16位二进制字符串每一位的1的数量:

enter image description here

我想生成300个16位的二进制向量,大致遵循上述分布。

最初,我的代码依赖于概率数组gengen,它计算每个位中出现1的次数。我生成了一个300x16值的随机矩阵,将每个值的值与概率进行比较,并将其分配给1和0.这类似于加权硬币方法。

然而,我收到的分布几乎是统一的。

gengen = [30, 28, 30, 30, 30, 26, 28, 28, 29, 23, 17, 8, 10, 12, 7, 6]

len = 16; % string length

% probability for 1 in each bit
prob_gengen = gengen./30;
% generate 100 random strings 
moreStrings = rand(300,len);
samplemore = []
for i = 1:300
  for k = 1:16
    disp(i)
    disp(k)
    if (prob_gengen(k) > moreStrings(i,k))
        samplemore(i,k) = 1;
    else
        samplemore(i,k) = 0;
    end
  end
end
G = reshape(samplemore,[16,300])

此代码绘制了最终分布:

colormap('default')
subplot(3,1,1)
bar(sum(G,2)); % summing along rows using DIM = 2
xlabel('Frequency Bin ');
title('Generator (16b) Generated');

enter image description here

如何获得类似于第一个条形图的分布?代码本身在MATLAB中,但我认为Python实现也可以。

1 个答案:

答案 0 :(得分:0)

我认为错误的主要来源是您获取G的重塑步骤。如果要将数据从300 x 16矩阵重新组织为16 x 3矩阵,则应transpose。使用reshape拆分旧的300个元素列,并将它们分散到新的16个元素列中。

但是,您可以使用bsxfun

完成所有这些操作而无需循环
gengen = [30, 28, 30, 30, 30, 26, 28, 28, 29, 23, 17, 8, 10, 12, 7, 6];
len = 16;
prob_gengen = gengen./30;
binvecs = bsxfun(@le, rand(300, len), prob_gengen);
bar(sum(binvecs, 1));

这是条形图,看起来很像上面的第一个条形图:

enter image description here

工作原理......

首先,使用rand创建一个介于0和1之间的300乘16的均匀生成的随机值。接下来,您需要根据prob_gengen向量中的概率检查每列中的随机值。例如,16 th 列的概率为0.2,这意味着(平均而言)您希望该列中五分之一的值为1,五分之四为零。您可以通过检查随机生成的值是否为less than or equal to此概率阈值来执行此操作。使用bsxfun根据需要展开向量prob_gengen,以便对所有行进行比较。