[英]Numpy - efficiently building 2d array from 1d arrays
我正在從numpy(Python 2.7)中的1d數組構建2d數組。 我正在尋找最有效的方法。 到目前為止,我想到了:
a=np.ones(100000)
# SUBSCRIPTING
n_dim=3
x=0
for i in xrange(0,1000):
x=np.zeros(shape=(100000,n_dim))
for j in xrange(0,n_dim):
x[:,j]=a*j
# ~1.574 s/1000 loops - joinind 3 1d arrays
# ~9.162 s/1000 loops - joinind 10 1d arrays
# STACKING
for i in xrange(0,1000):
x=a*0.
for j in xrange(1,n_dim):
x=np.vstack((x,a*j))
x=x.T
# ~1.786 s/1000 loops - joinind 3 1d arrays
# ~16.603 s/1000 loops - joinind 10 1d arrays
第一種方法(下標)是我想出的最快方法,而第二種方法(堆棧)的性能增益隨着我加入的一維數組的數量而增長。 當我需要重復很多步驟時,我想知道是否有更快的方法? 我願意采用一種解決方案,如果該解決方案可以顯着提高性能,那么它會變得不清楚。
也許我可以嘗試以限制堆棧操作數量的方式來堆棧數組(例如,連接4個1d數組的情況:首先堆棧數組1和2,然后是數組3和4,最后是結果數組)。
我的問題是關於從1d數組有效地構建2d數組。 我在這里使用的數組中的值是虛擬的。 在實際應用中,我加入的1d數組中的大多數值可能會有所不同。
由於numpy(默認情況下)按行優先順序存儲數組,因此按行設置值更有效。 因此,我將使用:
x=np.zeros(shape=(n_dim, 100000))
for j in range(0,n_dim):
x[j,:]=a*j
或者,您可以將x
定義為以列為主,然后,這與前面的代碼一樣快:
x=np.zeros(shape=(100000,n_dim), order='F')
for j in range(0,n_dim):
x[:,j]=a*j
您還可以使用numpy外積創建x
:
v = np.arange(n_dim)
x = np.outer(v, a)
這是使用vstack
糟糕方法; 您反復調用它,為每個j
創建一個新的x
x=a*0.
for j in xrange(1,n_dim):
x=np.vstack((x,a*j))
x=x.T
正確的方法是構建陣列列表,並且僅使用vstack
一次。
xlist=[]
for j in xrange(1,n_dim):
xlist.append(a*j)
x = np.array(xlist).T
在這種情況下, append
和vstack
一樣好,並且可能更快。 還有一個column_stack
函數。 關鍵區別在於,我利用了快速列表追加,以及array
(和vstack
)在其參數列表中采用許多項的能力。
如果您可以將循環作為列表理解來編寫,那就更好了
x = np.array([a*j for j in xrange(1,n_dim)])
插入預分配的數組通常是最快的選擇。 但是您應該熟悉這種“從列表構建”方法。
基本的np.array
表達式
np.array([[1,2,3],[4,5,6]])
就是這樣,從一維數組列表(或本例中的列表)構建2d。
np.array([a*0,a*1,a*2])
jakub
指出np.array
很慢。 對於n_dim=10
:
In [257]: timeit x=np.array([(a*j) for j in range(n_dim)]).T
1 loops, best of 3: 228 ms per loop
In [258]: timeit x=np.array([(a*j).tolist() for j in range(n_dim)]).T
1 loops, best of 3: 228 ms per loop
顯然, np.array
將輸入數組轉換為列表,然后從嵌套列表(或等效列表)開始進行其通常的構造。
In [259]: timeit x=np.vstack([(a*j) for j in range(n_dim)]).T
10 loops, best of 3: 24.9 ms per loop
數組列表中的vstack
速度要快得多。 比迭代vstack
(這是我期望的)。 基本上與Ramon's
行插入(和插入order='F'
)相同
In [272]: %%timeit
x=np.zeros((n_dim,a.shape[0]))
for j in range(n_dim):
x[j,:]=a*j
.....: x=x.T
.....:
10 loops, best of 3: 23.3 ms per loop
當concatenate
(由vstack
)被編譯時,我懷疑它的作用類似於迭代插入。 在源C代碼中,通常創建一個空的目標數組,然后用適當的值填充它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.