对于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。关于这个问题的任何阅读材料都会很棒!
答案 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”顺序,最后一个维度形成连续的块。