2017-06-15 162 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