如何确定numpy-array重塑策略

joe*_*pjp 7 python arrays numpy

对于python项目,我经常发现自己正在重塑和重新排列n维numpy数组.但是,我很难确定如何处理问题,可视化重塑方法结果的结果,并且知道我的解决方案是有效的.

在遇到这样的问题的那一刻,我的策略是启动ipython,加载一些样本数据并进行反复试验,直到找到transpose()s,reshape()和swapaxes()的组合.获得了理想的结果.它完成了工作,但没有真正了解正在发生的事情,并且经常产生难以维护的代码.

所以,我的问题是找到一个策略.你怎么处理这样的问题?当你必须以所需的格式塑造它时,你如何想象你头脑中的ndarray?你是如何做出正确的行动的?

为了使回答更具体,一个例子:

假设您要重塑以下3d数组

array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])
Run Code Online (Sandbox Code Playgroud)

到2d阵列,其中第三维的第一列放在第一,第二列放在第二,......等

结果应如下所示:

array([[ 0,  9, 18,  3, 12, 21,  6, 15, 24],
       [ 1, 10, 19,  4, 13, 22,  7, 16, 25],
       [ 2, 11, 20,  5, 14, 23,  8, 17, 26]])
Run Code Online (Sandbox Code Playgroud)

PS.关于这个主题的任何阅读材料都会很棒!

hpa*_*ulj 4

我经常玩弄 中的形状ipython。然而,为了让事情更清楚,我从具有不同维度的数组开始。

arr = np.arange(3*4*5).reshape(3,4,5)
Run Code Online (Sandbox Code Playgroud)

这样,就可以更轻松地识别轴如何移动,例如:

In [25]: arr.shape
Out[25]: (3, 4, 5)

In [26]: arr.T.shape
Out[26]: (5, 4, 3)

In [31]: arr.T.reshape(5,-1)
Out[31]: 
array([[ 0, 20, 40,  5, 25, 45, 10, 30, 50, 15, 35, 55],
       [ 1, 21, 41,  6, 26, 46, 11, 31, 51, 16, 36, 56],
       [ 2, 22, 42,  7, 27, 47, 12, 32, 52, 17, 37, 57],
       [ 3, 23, 43,  8, 28, 48, 13, 33, 53, 18, 38, 58],
       [ 4, 24, 44,  9, 29, 49, 14, 34, 54, 19, 39, 59]])
Run Code Online (Sandbox Code Playgroud)

作为不同的转置(不改变 3,4 的顺序)

In [38]: np.transpose(arr,[2,0,1]).shape
Out[38]: (5, 3, 4)

In [39]: np.transpose(arr,[2,0,1]).reshape(5,-1)
Out[39]: 
array([[ 0,  5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55],
       [ 1,  6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56],
       [ 2,  7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57],
       [ 3,  8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58],
       [ 4,  9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59]])
Run Code Online (Sandbox Code Playgroud)

我也喜欢在开发函数时使用像这样的“奇怪”形状的数组。这样,如果我确实弄乱了一些转置或广播,尺寸错误就会跳出来。经验告诉我,一旦尺寸正确,数值也将是正确的。或者至少影响值的错误类别与影响维度的错误类别完全不同。

我还大量地在开发代码中添加print arr.shape类似的语句,甚至assert x.shape==y.shape断言。

它还有助于标记尺寸:

M, N, L = 3, 4, 5
np.empty((M,N,L))
Run Code Online (Sandbox Code Playgroud)

或者像在einsum

np.einsum('ijk,kj->i', A, B) # if A is (M,N,L), B must be (L,N)
Run Code Online (Sandbox Code Playgroud)

/sf/answers/2093268971/是尝试理解和解释的示例rollaxis

另一个策略是查看 Python 函数代码numpy。他们常常接受axis论点。看看他们如何使用它们是有启发性的。有时,该特定内容axis会旋转到前面或末尾。有时,nd 数组会被重新整形为二维数组,将除一个轴之外的所有轴折叠为一个。其他方法通过构造和操作索引元组来实现通用性。更高级的功能与步幅和形状有关。

一个维度应该是第一个还是最后一个通常是一个优化问题 - 并且可能涉及易用性(广播、索引)和速度之间的权衡。请记住,对于“C”顺序,最后一个维度形成连续的块。