簡體   English   中英

Numpy-從1D數組高效構建2D數組

[英]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

在這種情況下, appendvstack一樣好,並且可能更快。 還有一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM