Python 交换 numpy 数组的维度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23943379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swapping the dimensions of a numpy array
提问by sponce
I would like to do the following:
我想做以下事情:
for i in dimension1:
for j in dimension2:
for k in dimension3:
for l in dimension4:
B[k,l,i,j] = A[i,j,k,l]
without the use of loops. In the end both A and B contain the same information but indexed differently.
不使用循环。最后,A 和 B 包含相同的信息,但索引不同。
I must point out that the dimension 1,2,3 and 4 can be the same or different. So a numpy.reshape() seems difficult.
我必须指出,维度 1、2、3 和 4 可以相同或不同。所以 numpy.reshape() 似乎很难。
采纳答案by unutbu
Please note: Jaime's answeris better. NumPy provides np.transpose
precisely for this purpose.
请注意:Jaime 的回答更好。NumPynp.transpose
正是为此目的而提供的。
Or use np.einsum; this is perhaps a perversion of its intended purpose, but the syntax is quite nice:
或者使用np.einsum; 这可能是对其预期目的的一种变态,但语法非常好:
In [195]: A = np.random.random((2,4,3,5))
In [196]: B = np.einsum('klij->ijkl', A)
In [197]: A.shape
Out[197]: (2, 4, 3, 5)
In [198]: B.shape
Out[198]: (3, 5, 2, 4)
In [199]: import itertools as IT
In [200]: all(B[k,l,i,j] == A[i,j,k,l] for i,j,k,l in IT.product(*map(range, A.shape)))
Out[200]: True
回答by metaperture
I would look at numpy.ndarray.shape and itertools.product:
我会看看 numpy.ndarray.shape 和 itertools.product:
import numpy, itertools
A = numpy.ones((10,10,10,10))
B = numpy.zeros((10,10,10,10))
for i, j, k, l in itertools.product(*map(xrange, A.shape)):
B[k,l,i,j] = A[i,j,k,l]
By "without the use of loops" I'm assuming you mean "without the use of nested loops", of course. Unless there's some numpy built-in that does this, I think this is your best bet.
当然,“不使用循环”是指“不使用嵌套循环”。除非有一些内置的 numpy 可以做到这一点,否则我认为这是你最好的选择。
回答by DSM
You could rollaxis
twice:
你可以rollaxis
两次:
>>> A = np.random.random((2,4,3,5))
>>> B = np.rollaxis(np.rollaxis(A, 2), 3, 1)
>>> A.shape
(2, 4, 3, 5)
>>> B.shape
(3, 5, 2, 4)
>>> from itertools import product
>>> all(B[k,l,i,j] == A[i,j,k,l] for i,j,k,l in product(*map(range, A.shape)))
True
or maybe swapaxes
twice is easier to follow:
或者swapaxes
两次更容易遵循:
>>> A = np.random.random((2,4,3,5))
>>> C = A.swapaxes(0, 2).swapaxes(1,3)
>>> C.shape
(3, 5, 2, 4)
>>> all(C[k,l,i,j] == A[i,j,k,l] for i,j,k,l in product(*map(range, A.shape)))
True
回答by Jaime
The canonical way of doing this in numpy would be to use np.transpose
's optional permutation argument. In your case, to go from ijkl
to klij
, the permutation is (2, 3, 0, 1)
, e.g.:
在 numpy 中执行此操作的规范方法是使用np.transpose
的可选排列参数。在您的情况下,从ijkl
到klij
,排列是(2, 3, 0, 1)
,例如:
In [16]: a = np.empty((2, 3, 4, 5))
In [17]: b = np.transpose(a, (2, 3, 0, 1))
In [18]: b.shape
Out[18]: (4, 5, 2, 3)
回答by kmario23
One can also leverage numpy.moveaxis()
for movingthe required axes to desired locations. Here is an illustration, stealing the example from Jaime's answer:
人们也可以利用numpy.moveaxis()
用于移动所需的轴到所需的位置。这是一个插图,从Jaime 的回答中窃取了示例:
In [160]: a = np.empty((2, 3, 4, 5))
# move the axes that are originally at positions [0, 1] to [2, 3]
In [161]: np.moveaxis(a, [0, 1], [2, 3]).shape
Out[161]: (4, 5, 2, 3)