Python 通过多维阵列的所有一维子阵列进行迭代
在python中迭代n维数组的所有一维子数组的最快方法是什么Python 通过多维阵列的所有一维子阵列进行迭代,python,multidimensional-array,numpy,Python,Multidimensional Array,Numpy,在python中迭代n维数组的所有一维子数组的最快方法是什么 例如考虑三维数组: import numpy as np a = np.arange(24) a = a.reshape(2,3,4) 迭代器的期望收益序列为: a[:,0,0] a[:,0,1] .. a[:,2,3] a[0,:,0] .. a[1,:,3] a[0,0,:] .. a[1,2,:] 你的朋友是slice()对象,numpy的ndarray.\uuu getitem\uuuuuuuuu()方法,可能还有ite
例如考虑三维数组:
import numpy as np
a = np.arange(24)
a = a.reshape(2,3,4)
迭代器的期望收益序列为:
a[:,0,0]
a[:,0,1]
..
a[:,2,3]
a[0,:,0]
..
a[1,:,3]
a[0,0,:]
..
a[1,2,:]
你的朋友是
slice()
对象,numpy的ndarray.\uuu getitem\uuuuuuuuu()
方法,可能还有itertools.chain。从\u iterable
可能有一种更有效的方法,但这应该是可行的
import itertools
import numpy as np
a = np.arange(24)
a = a.reshape(2,3,4)
colon = slice(None)
dimensions = [range(dim) + [colon] for dim in a.shape]
for dim in itertools.product(*dimensions):
if dim.count(colon) == 1:
print a[dim]
这就产生了(我省去了一点小代码来打印这张照片的左侧…):
这里的关键是,使用(例如)a[0,0,:]
索引a
相当于使用a[(0,0,切片(无))]
索引a。(这只是一般的python切片,不是特定于numpy的。为了向自己证明这一点,您可以使用\uuu getitem\uuuu
编写一个虚拟类,并在索引虚拟类实例时打印传入的内容。)
因此,我们想要的是0到nx、0到ny、0到nz等的所有可能组合,以及每个轴的None
但是,我们需要1D数组,因此我们需要过滤掉任何多于或少于一个无
(即我们不需要a[:,:,:]
,a[0,:,:]
,a[0,0,0]
等)
希望这有点道理,无论如何
编辑:我假设确切的顺序无关紧要。。。如果您需要问题中列出的确切顺序,则需要修改此…以下是此类迭代器的紧凑实现:
def iter1d(a):
return itertools.chain.from_iterable(
numpy.rollaxis(a, axis, a.ndim).reshape(-1, dim)
for axis, dim in enumerate(a.shape))
这将按照您在帖子中给出的顺序生成子数组:
for x in iter1d(a):
print x
印刷品
[ 0 12]
[ 1 13]
[ 2 14]
[ 3 15]
[ 4 16]
[ 5 17]
[ 6 18]
[ 7 19]
[ 8 20]
[ 9 21]
[10 22]
[11 23]
[0 4 8]
[1 5 9]
[ 2 6 10]
[ 3 7 11]
[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]
[0 1 2 3]
[4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]
这里的诀窍是迭代所有轴,并为每个轴将阵列重塑为二维阵列,其中的行是所需的一维子阵列。非常好!比我的解决方案优雅(高效)多了!我试图通过您个人资料中列出的.net网址向root用户发送电子邮件。如果你不想连接,那没关系。@FM:Actually
dim.count(None)
似乎比sum(如果item为None,dim中的item为1)
:)更具可读性。还有一个建议:用切片(None)替换None
的前两次出现
并删除包含第三次出现的None
@Sven的行-这一点很好!提醒我看曲棍球时不要回答问题。。。(加油!最后一个阶段真的是个钉子咬人!)我看到的一个问题是,循环生成的大约N个点中只有1个被实际使用。当N变大时,这可能是一个问题。考虑到这一点,对于我的特定应用程序来说,这可能不是一个严重的问题。(N是每个维度的点数)@fodon-确实如此。(这就是我说“可能有更有效的方法”时的意思)@Sven的解决方案避免了这一点,并且应该更快、更具可扩展性。斯文的绝对是一条路要走。唯一的缺点是,对于不熟悉numpy的人来说,它有点不可读。
[ 0 12]
[ 1 13]
[ 2 14]
[ 3 15]
[ 4 16]
[ 5 17]
[ 6 18]
[ 7 19]
[ 8 20]
[ 9 21]
[10 22]
[11 23]
[0 4 8]
[1 5 9]
[ 2 6 10]
[ 3 7 11]
[12 16 20]
[13 17 21]
[14 18 22]
[15 19 23]
[0 1 2 3]
[4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]
[16 17 18 19]
[20 21 22 23]