在Python中迭代3d数组中包含的2d数组

Rob*_*ith 3 python iteration numpy vectorization multidimensional-array

我已经看到很多问题要求以更快的方式迭代2d数组的每个元素,但是我没有找到一个很好的方法迭代3d数组以便在每个2d数组上应用函数.例如:

from scipy.fftpack import dct
X = np.arange(10000, dtype=np.float32).reshape(-1,4,4)
np.array(map(dct, X))
Run Code Online (Sandbox Code Playgroud)

在这里,我将浏览包含在3d维数组中的每个2d数组,(625,4,4)并对每个4X4数组应用DCT(离散余弦变换).我想知道是否有更合适的方法来实现这一目标.

谢谢

Pac*_*ler 6

Numpy功能:

在这种情况下,由于它dct是一个numpy函数,它具有内置的功能,可以在特定的轴上应用它.几乎所有的numpy函数都在完整的数组上运行,或者可以告诉它们在特定的轴(行或列)上运行.

所以只需通过利用函数axis参数dct:

dct( X, axis=2)
Run Code Online (Sandbox Code Playgroud)

你会得到一个相同的结果:

>>> ( dct(X, axis=2) == np.array(map(dct, X)) ).all()
True
Run Code Online (Sandbox Code Playgroud)

这比使用矩阵map情况下的函数快35倍(625,4,4):

%timeit dct(X, axis=2)
1000 loops, best of 3: 157 µs per loop

%timeit np.array(map(dct, X))
100 loops, best of 3: 5.76 ms per loop    
Run Code Online (Sandbox Code Playgroud)

一般Python函数:

在其他情况下,您可以vectorize使用np.vectorizenp.frompyfunc函数的python 函数.例如,如果您有一个执行标量操作的演示函数:

def foo(x): # gives an error if passed in an array
    return x**2

>>> X = np.arange(8, dtype=np.float32).reshape(-1,2,2)
>>> foo_arr = np.vectorize( foo)
>>> foo_arr(X)
array([[[  0.,   1.],
        [  4.,   9.]],

       [[ 16.,  25.],
        [ 36.,  49.]]])
Run Code Online (Sandbox Code Playgroud)

这里的讨论也可能对您有所帮助.正如他们所说,矢量化非numpy函数实际上并没有使它更快.

  • 谢谢.我没注意到在这种情况下可以使用dct的轴参数.关于你的一般解决方案,你在答案的最后部分描述的正是为什么我想知道np.vectorize的替代方案. (2认同)