[英]Efficiently Reshape 3D Numpy Array into 1D List Plus Coordinate Vector
我有一個大的嵌套數組a
(256x256x256),我需要重構為一個包含這樣的元素的列表:
[ (i,j,k), a[i,j,k] ]
我現在這樣做如下:
aflat = a.flatten().tolist()
coords = list(itertools.product(range(256), repeat=3))
thelist = [list(x) for x in zip(coords, aflat)]
這有效,但速度相當慢。
我可以通過刪除坐標向量的運行時生成並從文件中讀取它們來節省大約一秒鍾。 然而,主要的減速似乎是在最后一行,時間超過6秒。
有沒有更快的方法來生成我在Python中需要的數據結構?
正如@Pi評論的那樣,主要的問題是代碼創建了大量的列表,而Python花費了大量時間進行內存管理。 要消除這種情況,您可以使用numpy數組預分配數據,並使用其repeat
和tile
函數生成i,j,k
值:
# order='F' is important here so column-wise assignment can
# occur with a stride of 1. Switching the order results
# in a significant performance hit.
coords = numpy.zeros([a.size,4],'d',order='F')
NI, NJ, NK = a.shape
# build columns for (i,j,k) tuples using repeat and tile
coords[:,0] = numpy.repeat(range(NI),NJ*NK)
coords[:,1] = numpy.tile(numpy.repeat(range(NJ),NK), NI)
coords[:,2] = numpy.tile(range(NK), NI*NJ)
coords[:,3] = a.flatten()
這導致一個數組,其中每一行是(i,j,k,value)
。 它確實假設您的原始數組是行主要排序(N-n中的C排序數組)。
在我的計時中,基於2013年MacBook Pro上的Python 3.5中的十次迭代,每次轉換需要大約20秒來運行OP的轉換,並且使用此方法每次轉換僅需要大約8秒。
輸出格式實際上必須是一個列表,該數組可以在最后一步轉換為列表。 但是,在我的測試中,每次轉換的轉換時間增加到13秒。
要擴展@ wii上面的評論,你需要找到np.ndenumerate
。
通常,您將避免顯式創建列表並使用迭代器。 例如:
for (i,j,k), val in np.ndenumerate(your_3d_array):
assert val == your_3d_array[i,j,k]
# Note that we also could have done:
for ind, val in np.ndenumerate(your_3d_array):
assert val == your_3d_array[ind]
但是,如果您確實要創建完整的中間列表,則可以使用:
list(np.ndenumerate(your_3d_array))
作為一個更完整的例子:
In [1]: import numpy as np
In [2]: x = np.arange(3*4*5).reshape(3, 4, 5)
In [3]: x
Out[7]:
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]],
[[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29],
[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39]],
[[40, 41, 42, 43, 44],
[45, 46, 47, 48, 49],
[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59]]])
In [4]: list(np.ndenumerate(x))
Out [4]:
[((0, 0, 0), 0),
((0, 0, 1), 1),
((0, 0, 2), 2),
((0, 0, 3), 3),
...
((2, 3, 1), 56),
((2, 3, 2), 57),
((2, 3, 3), 58),
((2, 3, 4), 59)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.