2017-06-15 165 views
1

比方說,我有一個名爲purity_list一個熊貓數據框如下:矢量化版本

In[]: purity_list 
Out[]: 
    48 49 50 
2 0.1 0.9 0.3 
A 0.2 -0.5 -0.6 
4 0.3 0.8 0.9 

我想這比較其他numpy的陣列,並得到最大的+ ve值,如果沒有+ ve值,我想要最低值。

所以我們可以說我是如下比較這被稱爲purities numpy的數組:

In[]: purities 
Out[]: 
array([-0.2, 0.2, -0.8]) 

最接近的量化代碼我現在所擁有的是這樣的:

purity_list = np.where(np.absolute(purity_list) > np.absolute(purities), 
         purity_list, purities) 

當我運行該代碼,這裏是我將得到的:

In[]: purity_list 
Out[]: 
    48 49 50 
2 -0.2 0.9 -0.8 
A -0.2 -0.5 -0.8 
4 0.3 0.8 0.9 

我真正想要的是som略有不同。我有非矢量化的邏輯在這裏:

for i, v1 in enumerate(purity_list): 
    for j, v2 in enumerate(v1): 
     if v2 > 0 or purities[j] > 0: 
      purity_list.iloc[i, j] = np.max(purity_list.iloc[i, j], purities[j]) 
     else: 
      purity_list.iloc[i, j] = np.min(purity_list.iloc[i, j], purities[j]) 

結果這將是:

In[]: purity_list 
Out[]: 
    48 49 50 
2 0.1 0.9 0.3 
A 0.2 0.2 -0.8 
4 0.3 0.8 0.9 

這就是我要尋找的結果。我重複這個聲明超過10萬次,我的數組非常大,所以我需要一個向量化版本。性能是關鍵。

回答

1

您的np.where版本的邏輯不太正確。考慮一下當負值大於正值時,會發生什麼情況。然而,工具的選擇是合理的。因此,所有你需要做的是正確的狀態,以更好地匹配你的目標是什麼了:

np.where((purity_list < 0) & (purities < 0), 
     np.where(purity_list < purities, purity_list, purities), 
     np.where(purity_list > purities, purity_list, purities)) 
Out[42]: 
array([[ 0.1, 0.9, 0.3], 
     [ 0.2, 0.2, -0.8], 
     [ 0.3, 0.8, 0.9]]) 

如果嵌套np.where感覺傻傻的,邏輯可以組合:

np.where(((purity_list < 0) & (purities < 0) & (purity_list < purities)) 
     |(((purity_list > 0) | (purities > 0)) & (purity_list > purities)), 
     purity_list, purities) 
Out[43]: 
array([[ 0.1, 0.9, 0.3], 
     [ 0.2, 0.2, -0.8], 
     [ 0.3, 0.8, 0.9]]) 

但我發現它更清晰的第一種方式。

+1

偉大的解決方案。我測試了你的兩個版本,它適用於所有其他情況,以及我沒有在我的問題中顯示的情況。我準備了我自己的條件,它的工作原理:'((((np.sign(purity_list)+ np.sign(purities))> = np.zeros((1,len(purities))))^( pure_list> purities))'。我認爲這也是對的,但如果不是,請告訴我。 –

+1

雖然你可以簡化一點,但看起來很合適。 'np.zeros((1,len(purities)))'可以用一個簡單的'0'替換,如果你在後面的句子中反轉'>',或者在另一箇中切換'purity_list'和'purities'參數,你可以擺脫否定(因爲你不關心當'purity_list'和'purities'是相同的時候會被挑選出來,並且你可以用一個xor來吸納一個子句的否定),對於更清晰的條件:' ((np.sign(purity_list)+ np.sign(purities))> = 0)^(purity_list <純度)'。 – EFT