2016-08-30 74 views
2

我有一個數組numpy的矢量零階插值

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的末尾放置一列1,則這將是3.我也可以接受-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(種類=零)
    • 這似乎需要一個外蟒環
  • R> p和numpy的其中
    • 似乎也需要一個外部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不支持矢量(1,2)。

numpy.vectorise解決方案,還是Cython?我正在尋找一個快速解決方案。

+0

我不是百分百確定矢量是在這種情況下完全合理的。如果數據靠近內存,允許使用SIMD,則矢量化是有意義的。這裏不一定是這種情況,即假設對於第一行,你的條件已經在第九列完成,而對於第二行,它可能只在第二列滿足。如果您將向量化代碼設置爲優先級,那麼您最終可能會得到不必要的雙重檢查代碼,從而導致代碼耗時。 –

+0

@MohammedLi正如問題'「數百萬行,〜10列」'中所述,我確實認爲矢量化解決方案適合這個問題。首先,因爲它不會在python級迭代這麼多的行,其次是因爲col數量有限,所以它不會在任何行上走得太慢。 – Divakar

+0

@wwii看着預期的解決方案,我將其解釋爲「第一列索引,其中p大於r」。 OP你能澄清一下嗎? – Divakar

回答

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])