Numpy矢量化零阶插值

时间:2016-08-30 14:50:28

标签: python numpy optimization vectorization

我有一个数组

p = [[0.9, 0.95, 0.99],
     [0.89, 0.94, 0.98],
     [0.9, 0.95, 0.99],
     [0.91, 0.96, 0.97],
    ]

和每行的统一随机数

r = [0.5, 
     0.9,
     0.3,
     0.99] 

我想知道p仍然小于r的最后一列索引,即

c = [0, 1, 0, 3]

对于最后一种情况,没有值更小。如果在p的末尾放置1s的列,那么这将是3.对我来说,A -1也是可接受的。

天真的解决方案:

c = []
for prow, ri in zip(p, r):
    ci = numpy.interp(ri, prow, arange(len(prow)))
    c.append(int(numpy.ceil(ci)))

print c
[0, 1, 0, 3]

但我正在寻找一种快速的矢量化解决方案,适用于大型阵列(数百万行,~10列)。

我研究了这些解决方案:

  • scipy.interpolate.interp1d(种类=零)
    • 这似乎需要一个外部python循环
  • r> p和numpy.where
    • 似乎也需要一个外部python循环
  • 使用numpy.random.choice

对于最后一个,我会放置(差异)概率而不是累积概率:

p = [[0.9, 0.05, 0.04],
     [0.89, 0.05, 0.04],
     [0.9, 0.05, 0.04],
     [0.91, 0.05, 0.01],
    ]

但是numpy.random.choice不支持矢量化(12)。

numpy.vectorise是解决方案,还是Cython?我正在寻找一个快速的解决方案。

1 个答案:

答案 0 :(得分:3)

这是使用broadcasting -

的一个矢量化解决方案
mask = (p > r[:,None])
out = np.where(mask.any(1),mask.argmax(1),p.shape[1])

示例运行 -

In [50]: p
Out[50]: 
array([[ 0.9 ,  0.95,  0.99],
       [ 0.89,  0.94,  0.98],
       [ 0.9 ,  0.95,  0.99],
       [ 0.91,  0.96,  0.97]])

In [51]: r
Out[51]: array([ 0.5 ,  0.9 ,  0.3 ,  0.99])

In [52]: mask = (p > r[:,None]) # 2D Mask of row-wise comparisons

In [53]: mask
Out[53]: 
array([[ True,  True,  True],
       [False,  True,  True],
       [ True,  True,  True],
       [False, False, False]], dtype=bool)

In [54]: np.where(mask.any(1),mask.argmax(1),p.shape[1])
Out[54]: array([0, 1, 0, 3])