如何确定numpy-array重塑策略

时间:2015-05-28 17:34:34

标签: python arrays numpy

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

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

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

为了使回答更具体,一个可以使用的例子:

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

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]])

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

结果应如下所示:

.draggable-box

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

1 个答案:

答案 0 :(得分:4)

我经常在ipython中玩形状。但是,为了使事情更清楚,我从具有不同维度的数组开始。

arr = np.arange(3*4*5).reshape(3,4,5)

这样,更容易识别轴的移动方式,例如:

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]])

其中作为不同的转置(不切换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]])

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

我还可以使用print arr.shape类似的语句,甚至是assert x.shape==y.shape断言自由地使用开发代码。

它还有助于标注尺寸:

M, N, L = 3, 4, 5
np.empty((M,N,L))

或喜欢einsum

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

https://stackoverflow.com/a/29903842/901925是尝试理解和解释rollaxis的一个示例。

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

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