使用numpy random进行快速随机选择

时间:2014-06-20 00:57:43

标签: python-2.7 numpy random

编辑:我把实际值放在一起,这样代码就可以了:

我有4个相同长度的numpy数组:

R = np.array[ 0.39374042  0.55270474  0.50848503  0.63725071  0.0350963   0.67203288
  0.03419264  0.60936204  0.3819783   0.17653394  0.76278053  0.85589961
  0.91961392  0.85265048  0.6108294   0.15980841  0.76017363  0.21771499
  0.25927199  0.39172983  0.36364338  0.77375089  0.92969549  0.01237327
  0.12195605  0.5587532   0.70229425  0.82809111  0.06700928  0.64284712
  0.15944779  0.76857694  0.35924588  0.75636962  0.25039875  0.60632514
  0.49124143  0.73741699  0.2178207   0.15998988  0.79652839  0.73693122]

R包含介于0和1之间的np.random.uniform个值

RGB = np.array[[[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[  0 110 105]
  [174  40 109]
  [  5  59 158]
  [  0 181 107]]

 [[  0 161  73]
  [182  48  57]
  [174  40 109]
  [ 32 134  39]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[174  40 109]
  [  5  59 158]
  [  0 181 107]
  [193  93 160]]

 [[219  99 109]
  [174  40 109]
  [  0 181 107]
  [104 162  26]]

 [[ 63 114 221]
  [  0 172 192]
  [ 32  77 211]
  [187  77 195]]

 [[219  99 109]
  [238  67  47]
  [ 87 194  65]
  [176 187   0]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[110 213 158]
  [235 154 164]
  [  0 190 211]
  [187  77 195]]

 [[219  99 109]
  [110 213 158]
  [235 154 164]
  [193  93 160]]

 [[219  99 109]
  [110 213 158]
  [ 87 194  65]
  [  0 181 107]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[219 162 208]
  [110 213 158]
  [235 154 164]
  [167 233 196]]

 [[110 213 158]
  [235 154 164]
  [255 226 130]
  [167 233 196]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[239 212 240]
  [136 220 234]
  [208 242 247]
  [167 233 196]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]

 [[118 187 239]
  [219 162 208]
  [136 220 234]
  [  0 190 211]]]

RGB包含4组RGB颜色值

A = np.array[ -1  -1  -1  -1  -1  -1 159 148  -1  -1  -1  -1  45  97  57  80  -1  -1
  60  84  86  -1  -1  -1 112  72  -1  -1  -1  -1 133  -1  -1  -1  -1  -1
  -1  -1  -1  -1  -1  -1]

A包含-1 B中4个值集的索引

B = np.array[[-1.54525517  1.09915125 -1.74258272  3.18868664]
 [-1.04522579  1.04443564 -1.83606995  2.8368601 ]
 [-2.51080789  1.4980096  -1.62047649  3.63327478]
 [-0.75381136  0.38494135 -1.76551145  3.13438146]
 [-0.42398121  1.45934623 -2.04842952  2.0130645 ]
 [-3.58516396  1.51736923 -1.40004578  4.46784052]
 [ 0.46980945  0.23242436  0.15812529  0.1396409 ]
 [ 0.02950557  0.43429909  0.34304701  0.19314833]
 [-2.44568468  0.98038089 -1.01581931  3.4811231 ]
 [ 1.38051381  0.11766208 -1.64270991  1.14453402]
 [-2.90620565  2.2622749  -1.17507929  2.81901003]
 [-2.11827269  0.28090219 -0.94480948  3.78217997]
 [ 0.07434589  0.03948412  0.45858244  0.42758754]
 [ 0.10902808  0.29206381  0.50180905  0.09709906]
 [ 0.02106152  0.62921187  0.12285574  0.22687087]
 [ 0.25688419  0.62417539  0.01976311  0.09917731]
 [-2.56431038  0.58433235 -0.32521341  3.30519143]
 [ 3.34007944 -0.24491683 -1.39262584 -0.70253677]
 [ 0.43784474  0.09927102  0.12535527  0.33752897]
 [ 0.18369437  0.15869915  0.55640207  0.10120441]
 [ 0.13323323  0.23276694  0.33810426  0.29589556]
 [ 2.31472564 -0.25736362 -0.51265688 -0.54470514]
 [-3.13602078  2.46578654  0.08271576  1.58751849]
 [-2.08295869 -0.0948967   0.37305594  2.80479945]
 [ 0.39357387  0.12289595  0.12890858  0.3546216 ]
 [ 0.3637729   0.35308756  0.03283074  0.25030881]
 [ 0.91809484  0.00616419  0.47102103 -0.39528007]
 [-2.10633552  1.9717707   0.71079464  0.42377018]
 [-2.63786465  0.31323965  1.15219987  2.17242513]
 [ 4.66105371 -0.67514766 -0.17463501 -2.81127104]
 [ 0.4466582   0.12232826  0.19249585  0.2385177 ]
 [-1.1656546   1.27760641  1.48320113 -0.59515294]
 [-2.54309788  0.61607798  1.90256384  1.02445605]
 [ 3.38699312 -0.695849    0.92595314 -2.61709726]
 [-3.3691958   2.67546554  1.66471811  0.02901215]
 [-2.01283737 -0.53906846  2.02201185  1.52989397]
 [-0.7635726   0.59671731  2.45595894 -1.28910365]
 [-1.6913111   0.68635463  2.63177913 -0.62682267]
 [ 1.67630612 -0.3755707   2.14031351 -2.44104893]
 [-2.03409447  2.03385782  2.43486791 -1.43463126]
 [-2.68827085 -0.01102552  2.97885322  0.72044315]
 [ 6.15409418 -1.17188198  1.36416304 -5.34637524]]

B包含4个添加到1的值

我想要做的是创建一个新的数组N,它将包含使用与此类似的方法选择的RGB值,但使用nympy来避免耗时的循环

循环的代码示例:

new_array = []

for i in range(len(A)):
    if A[i] != -1:
        a = B[i][0]
        b = B[i][0] + a
        c = B[i][0] + b

        u = RGB[i][0]
        v = RGB[i][0]
        w = RGB[i][0]
        x = RGB[i][0]

        random = R[i]

        if a <= random:
             new_array = new_array + [u]
        elif b <= random:
             new_array = new_array + [v]
        elif c <= random:
             new_array = new_array + [w]
        else:
             new_array = new_array + [x]

    else:
        new_array = new_array + [0 0 0]

有没有办法在numpy中完全重写这个功能? 感谢

1 个答案:

答案 0 :(得分:1)

我试着解释这个问题。

  • 指向概率向量B
  • 的输入数组A(N个值为0..M-1或-1的整数)
  • 输入数组B(M x 4)给出概率(每行总和为1)
  • 颜色表RGB(N x 4 x 3),提供RGB三元组可供选择
  • 包含均匀分布的随机值[0,1]
  • 的输入向量R(N)

所以,对于A的每个值:

  • 从B
  • 中挑选概率向量
  • 随机值用于选择从RGB
  • 中的同一行中选择四个备选项中的哪一个

此外,还有两个额外的规则:

  • 如果A [n] == - 1,则相应的输出颜色为黑色
  • 如果B [n]中存在负概率,则相应的输出颜色为黑色

输出将是Nx3颜色数组。


因此,让我们首先构造一个干净的概率向量,以便不可能的组合由[-1,0,0,0]表示。

# get the number of rows:
N = len(A)

# create a boolean array to show which indices in A are valid
A_valid = (A != -1)

# get B vectors for all valid points in A
B_vectors = B[A[A_valid]]

# clean the B_vectors so that if there are <0 vectors, they are replaced by -1,0,0,0
B_vectors[numpy.amin(B_vectors, axis=1) < 0] = [-1.0, 0.0, 0.0, 0.0]

# create a clean probability table (N x 4)
probs = numpy.empty((N, 4))
# fill in the probabilities where they can be picked form B
probs[A_valid] = B_vectors
# fill the rest with -1,0,0,0
probs[-A_valid] = [-1, 0, 0, 0]

现在我们有一个表,其中有实数概率(正数总和为1)或(-1,0,0,0),如果A中有-1或者特定行中B中有一个不可能的概率向量。

如果形成累积概率,则概率向量更容易使用。例如,概率向量(.2,.3,.4,.1)被转换为(。2,.5,.9,1.0)。在这种形式中,可以直接比较随机数r,以查看应该选择哪个bin。

下一步是使用这种方法获得颜色箱(0,1,2,3):

# cumulative probabilities
cumprobs = numpy.cumsum(probs, axis=1)

# color indices
cidx = numpy.zeros(N)

# compare the colour indices to the random vector r
cidx[r > cumprobs[:,0]] = 1
cidx[r > cumprobs[:,1]] = 2
cidx[r > cumprobs[:,2]] = 3

(由于一些奇怪的原因,numpy中没有执行此操作的功能。numpy.digitize仅适用于1-d向量。)

应该注意的是,对于某些行,累积概率为(。2,.5,.9,1.0),同一行的r为0.95,cidx为0(在数组创建之后) ),然后设置为1(因为r> .2),然后设置为2(因为r> .5),最后设置为3(因为r> .9)。

然后我们可以使用cidxRGB

创建输出颜色表
# pick the item defined by cidx for each row
rainbow = RGB[arange(N), cidx]

这将选择该行上相应cidxRGB值指定的颜色。

最后,我们必须将所有无效颜色变黑:

# if the probability starts with -1, then we'll blacken the color out
rainbow[probs[:,0] < 0.] = [0,0,0]

现在结果应该在rainbow