2016-09-21 72 views
1

我对Python非常陌生,我试图习惯于执行Python的数组操作,而不是在数组中循环。下面是那种环接动作我做的一个例子,但我无法制定出不依赖于循环合适的纯数组操作:使用多个相同数组索引的数组操作

import numpy as np 

def f(arg1, arg2): 
    # an arbitrary function 


def myFunction(a1DNumpyArray): 
    A = a1DNumpyArray  

    # Create a square array with each dimension the size of the argument array. 
    B = np.zeros((A.size, A.size)) 

    # Function f is a function of two elements of the 1D array. For each 
    # element, i, I want to perform the function on it and every element 
    # before it, and store the result in the square array, multiplied by 
    # the difference between the ith and (i-1)th element. 
    for i in range(A.size): 
    B[i,:i] = f(A[i], A[:i])*(A[i]-A[i-1]) 

    # Sum through j and return full sums as 1D array. 
    return np.sum(B, axis=0) 

总之,我整合功能,有两个相同数组的元素作为参数,返回积分结果数组。

有没有更紧凑的方式来做到这一点,而不使用循环?

+0

现在阅读起来比较容易。任何你想妥协的理由? – erip

+0

我被一位资深Pythoneer告知:“不要使用循环来操作数组,使用数组操作。”显然,如果这太过于妥协易读性,我会坚持循环。 –

+1

我想说一个更好的规则是“不要使用循环来操作数组,如果存在一个数组操作来执行你所需要的操作”。 – Kevin

回答

0

使用任意f函数,而这个[i, :i]业务通过传递循环而变得复杂。

大部分快速编译的numpy操作对整个数组或整行和/或列起作用,并且可以有效地并行执行。循环固有的循环(来自一个循环的值取决于前一个循环)不适合。每个循环中不同大小的列表或数组也是一个很好的指示器,“矢量化”将很困难。

for i in range(A.size): 
    B[i,:i] = f(A[i], A[:i])*(A[i]-A[i-1]) 

与样品A和已知f(那样简单arg1*arg2),我会产生B阵列,并寻找治疗B作为一个整体的图案。乍一看,它看起来像你的B是一个较低的三角形。有些功能可以帮助索引这些内容。但是最后的总和可能会改变这幅画。

有时我会用自下而上的方法解决这些问题,首先尝试去除内部循环。但在这种情况下,我认为需要采取某种全方位的方法。