什麼是在python中遍歷n維數組的所有一維子數組的最快方法。通過多維數組的所有1維子陣列進行迭代
例如,考慮3-d數組:
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,:]
什麼是在python中遍歷n維數組的所有一維子數組的最快方法。通過多維數組的所有1維子陣列進行迭代
例如,考慮3-d數組:
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,:]
這裏是一個緊湊的實現這樣一個迭代器:
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]
這裏的竅門是遍歷所有軸,並且對於每個軸重塑陣列的二維陣列的行,其中在期望的一維子陣列。
你的朋友都是slice()
對象,numpy的的ndarray.__getitem__()
方法,以及可能itertools.chain.from_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,:] --> [0 1 2 3]
a[0,1,:] --> [4 5 6 7]
a[0,2,:] --> [ 8 9 10 11]
a[0,:,0] --> [0 4 8]
a[0,:,1] --> [1 5 9]
a[0,:,2] --> [ 2 6 10]
a[0,:,3] --> [ 3 7 11]
a[1,0,:] --> [12 13 14 15]
a[1,1,:] --> [16 17 18 19]
a[1,2,:] --> [20 21 22 23]
a[1,:,0] --> [12 16 20]
a[1,:,1] --> [13 17 21]
a[1,:,2] --> [14 18 22]
a[1,:,3] --> [15 19 23]
a[:,0,0] --> [ 0 12]
a[:,0,1] --> [ 1 13]
a[:,0,2] --> [ 2 14]
a[:,0,3] --> [ 3 15]
a[:,1,0] --> [ 4 16]
a[:,1,1] --> [ 5 17]
a[:,1,2] --> [ 6 18]
a[:,1,3] --> [ 7 19]
a[:,2,0] --> [ 8 20]
a[:,2,1] --> [ 9 21]
a[:,2,2] --> [10 22]
a[:,2,3] --> [11 23]
這裏的關鍵是,索引a
與(例如)a[0,0,:]
等同於用a[(0,0,slice(None))]
索引一個。 (這只是一般的python切片,沒有任何特定的numpy,爲了向你自己證明,你可以編寫一個虛擬類,只需要一個__getitem__
,並打印當你索引虛擬類的實例時傳入的內容。
所以,我們想要的是每個軸的0到nx,0到ny,0到nz等等和None
的每種可能組合。
但是,我們希望一維數組,所以我們需要過濾掉任何與多於或少於一個None
(即我們不想a[:,:,:]
,a[0,:,:]
,a[0,0,0]
等)。
希望這有一定道理,反正...
編輯:我假設的確切順序並不重要...如果你需要的確切命令你在你的問題一一列出,你會需要修改這個...
@FM - 好點,這更可讀。謝謝! – 2011-04-16 18:15:53
@FM:實際上'dim.count(無)'看起來比'總和(如果物品爲無,則爲暗物品1)'' – 2011-04-16 19:26:29
@Sven - 再一次,優點!我忽略了顯而易見的,那裏... – 2011-04-16 19:34:13
非常好!比我的解決方案更優雅(更高效)! – 2011-04-16 19:24:26
真棒解決方案! – fodon 2011-04-16 22:24:29
我試圖向您發送一封電子郵件給您的個人資料上列出的.net網址的root用戶。如果你不想連接,那很好。 – fodon 2011-04-17 16:40:24