【发布时间】:2015-05-28 12:47:03
【问题描述】:
我有一个 numpy 数组,它只有几个非零条目,可以是正数或负数。例如。像这样:
myArray = np.array([[ 0. , 0. , 0. ],
[ 0.32, -6.79, 0. ],
[ 0. , 0. , 0. ],
[ 0. , 1.5 , 0. ],
[ 0. , 0. , -1.71]])
最后,我想收到一个列表,其中该列表的每个条目对应于 myArray 的一行,并且是函数输出的累积乘积,函数输出取决于 myArray 的相应行和另一个列表的条目(在下面的例子称为 l)。 各个术语取决于 myArray 条目的符号:当它为正时,我应用“funPos”,当它为负时,我应用“funNeg”,如果条目为 0,则术语将为 1。所以在示例中上面的数组将是:
output = [1*1*1 ,
funPos(0.32, l[0])*funNeg(-6.79,l[1])*1,
1*1*1,
1*funPos(1.5, l[1])*1,
1*1*funNeg(-1.71, l[2])]
我实现了这个,如下所示,它给了我想要的输出(注意:这只是一个高度简化的玩具示例;实际的矩阵要大得多,函数也更复杂)。我遍历数组的每一行,如果行的和为0,我不需要做任何计算,输出只是1。如果不等于0,我遍历这一行,检查符号每个值并应用适当的函数。
import numpy as np
def doCalcOnArray(Array1, myList):
output = np.ones(Array1.shape[0]) #initialize output
for indRow,row in enumerate(Array1):
if sum(row) != 0: #only then calculations are needed
tempProd = 1. #initialize the product that corresponds to the row
for indCol, valCol in enumerate(row):
if valCol > 0:
tempVal = funPos(valCol, myList[indCol])
elif valCol < 0:
tempVal = funNeg(valCol, myList[indCol])
elif valCol == 0:
tempVal = 1
tempProd = tempProd*tempVal
output[indRow] = tempProd
return output
def funPos(val1,val2):
return val1*val2
def funNeg(val1,val2):
return val1*(val2+1)
myArray = np.array([[ 0. , 0. , 0. ],
[ 0.32, -6.79, 0. ],
[ 0. , 0. , 0. ],
[ 0. , 1.5 , 0. ],
[ 0. , 0. , -1.71]])
l = [1.1, 2., 3.4]
op = doCalcOnArray(myArray,l)
print op
输出是
[ 1. -7.17024 1. 3. -7.524 ]
这是想要的。
我的问题是是否有更有效的方法来做到这一点,因为这对于大型阵列来说非常“昂贵”。
编辑: 我接受了 gabhijit 的回答,因为他提出的纯 numpy 解决方案似乎是我正在处理的数组中最快的解决方案。请注意,RaJa 还提供了一个不错的工作解决方案,它需要 panda,并且 dave 的解决方案也可以正常工作,可以作为如何使用生成器和 numpy 的“apply_along_axis”的一个很好的例子。
【问题讨论】:
标签: python arrays performance numpy