Numpy 沿轴应用并获取行索引

sla*_*law 11 python numpy

我有一个二维数组(它实际上非常大并且是另一个数组的视图):

x = np.array([[0, 1, 2],
          [1, 2, 3],
          [2, 3, 4],
          [3, 4, 5]]
        )
Run Code Online (Sandbox Code Playgroud)

我有一个处理数组每一行的函数:

def some_func(a):
    """
    Some function that does something funky with a row of numbers
    """
    return [a[2], a[0]]  # This is not so funky

np.apply_along_axis(some_func, 1, x)
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是调用该np.apply_along_axis函数的某种方式,以便我可以访问行索引(对于正在处理的行),然后能够使用此函数处理每一行:

def some_func(a, idx):
    """
    I plan to use the index for some logic on which columns to
    return. This is only an example
    """
    return [idx, a[2], a[0]]  # This is not so funky
Run Code Online (Sandbox Code Playgroud)

hpa*_*ulj 1

对于 axis=1 的二维数组,apply_along_axis与数组行的迭代相同

In [149]: np.apply_along_axis(some_func, 1, x)
Out[149]: 
array([[2, 0],
       [3, 1],
       [4, 2],
       [5, 3]])
In [151]: np.array([some_func(i) for i in x])
Out[151]: 
array([[2, 0],
       [3, 1],
       [4, 2],
       [5, 3]])
Run Code Online (Sandbox Code Playgroud)

对于 axis=0 我们可以迭代x.Tapply_along_axis当数组是 3d 时更有用,并且我们想要迭代除一维之外的所有维度。这样就可以省去一些乏味的事情。但这不是一个速度解决方案。

通过修改后的函数,我们可以使用标准enumerate来获取行和索引:

In [153]: np.array([some_func(v,i) for i,v in enumerate(x)])
Out[153]: 
array([[0, 2, 0],
       [1, 3, 1],
       [2, 4, 2],
       [3, 5, 3]])
Run Code Online (Sandbox Code Playgroud)

或者使用简单的范围迭代:

In [157]: np.array([some_func(x[i],i) for i in range(x.shape[0])])
Out[157]: 
array([[0, 2, 0],
       [1, 3, 1],
       [2, 4, 2],
       [3, 5, 3]])
Run Code Online (Sandbox Code Playgroud)

有多种工具可以获取更高维度的索引,例如ndenumeratendindex

快速解决方案 - 一次处理所有行:

In [158]: np.column_stack((np.arange(4), x[:,2], x[:,0]))
Out[158]: 
array([[0, 2, 0],
       [1, 3, 1],
       [2, 4, 2],
       [3, 5, 3]])
Run Code Online (Sandbox Code Playgroud)