Numpy dizilerinin listesini tek bir numpy dizisine nasıl dönüştürebilirim?


117

Varsayalım ki;

LIST = [[array([1, 2, 3, 4, 5]), array([1, 2, 3, 4, 5],[1,2,3,4,5])] # inner lists are numpy arrays

Dönüştürmeye çalışıyorum;

array([[1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5],
       [1, 2, 3, 4, 5])

Şu anda vstack üzerinde yineleyerek çözüyorum ama özellikle büyük LIST için gerçekten yavaş

En verimli yol için ne önerirsiniz?


5
LIST = [[array([1, 2, 3, 4, 5]), array([1, 2, 3, 4, 5],[1,2,3,4,5])]bu doğru python sözdizimi değil. Lütfen açıkla.
Marcin

Yanıtlar:


149

Genel olarak, herhangi bir eksen boyunca tüm dizi dizilerini birleştirebilirsiniz:

numpy.concatenate( LIST, axis=0 )

ama do listesinde şekil ve her dizinin boyutluluk hakkında endişe etmek (2 boyutlu 3x5 çıkışı için, onlar zaten tüm 2 boyutlu n-by-5 diziler olduğundan emin olmak için gerekmez) var. 1 boyutlu dizileri 2 boyutlu bir çıktının satırları olarak birleştirmek istiyorsanız, boyutlarını genişletmeniz gerekir.

Jorge'nin cevabının işaret ettiği gibi stack, numpy 1.10'da tanıtılan işlev de var :

numpy.stack( LIST, axis=0 )

Bu tamamlayıcı yaklaşımı alır: her bir girdi dizisinin yeni bir görünümünü oluşturur ve birleştirmeden önce fazladan bir boyut ekler (bu durumda, solda, böylece her n-element 1D dizisi, 1'e n2B bir dizi olur). Yalnızca tüm giriş dizileri aynı şekle sahipse çalışır - hatta birleştirme ekseni boyunca bile.

vstack(veya eşdeğer olarak row_stack) çoğu zaman kullanımı daha kolay bir çözümdür çünkü 1 ve / veya 2 boyutlu diziler dizisini alır ve tüm listeyi bir araya getirmeden önce gerekli olduğunda ve yalnızca gerektiğinde boyutluluğu otomatik olarak genişletir. Yeni bir boyutun gerekli olduğu yerde, sola eklenir. Yine, yinelemeye gerek kalmadan tüm listeyi tek seferde birleştirebilirsiniz:

numpy.vstack( LIST )

Bu esnek davranış aynı zamanda sözdizimsel kısayolla da sergilenir numpy.r_[ array1, ...., arrayN ](köşeli parantezlere dikkat edin). Bu, açıkça adlandırılmış birkaç diziyi birleştirmek için iyidir, ancak sizin durumunuz için iyi değildir çünkü bu sözdizimi, sizin gibi bir dizi dizisini kabul etmeyecektir LIST.

Ayrıca yatay (sütun şeklinde) istifleme için benzer bir işlev column_stackve kısayol ve neredeyse -analog bir işlev vardır — bazı nedenlerden dolayı ikincisi daha az esnektir (giriş dizilerinin boyutsallığı konusunda daha katıdır ve birleştirmeye çalışır) 1-D dizileri sütun olarak ele almak yerine uçtan uca).c_[...]hstack

Son olarak, 1 boyutlu dizilerin dikey yığınlanması durumunda, aşağıdakiler de işe yarar:

numpy.array( LIST )

... çünkü diziler, başlangıca yeni bir boyut ekleyerek diğer dizilerin bir dizisinden oluşturulabilir.


5
Sanırım çıktı olarak bir 2d dizisi istedi.
Beefster

8

NumPy sürüm 1.10'dan başlayarak, yöntem yığınına sahibiz . Herhangi bir boyuttaki dizileri yığınlayabilir (tümü eşit):

# List of arrays.
L = [np.random.randn(5,4,2,5,1,2) for i in range(10)]

# Stack them using axis=0.
M = np.stack(L)
M.shape # == (10,5,4,2,5,1,2)
np.all(M == L) # == True

M = np.stack(L, axis=1)
M.shape # == (5,10,4,2,5,1,2)
np.all(M == L) # == False (Don't Panic)

# This are all true    
np.all(M[:,0,:] == L[0]) # == True
all(np.all(M[:,i,:] == L[i]) for i in range(10)) # == True

Zevk almak,


2

Hız performansı için bazı yöntemleri kontrol ettim ve hiçbir fark olmadığını gördüm ! Tek fark, bazı yöntemleri kullanarak boyutu dikkatlice kontrol etmeniz gerektiğidir.

Zamanlama:

|------------|----------------|-------------------|
|            | shape (10000)  |  shape (1,10000)  |
|------------|----------------|-------------------|
| np.concat  |    0.18280     |      0.17960      |
|------------|----------------|-------------------|
|  np.stack  |    0.21501     |      0.16465      |
|------------|----------------|-------------------|
| np.vstack  |    0.21501     |      0.17181      |
|------------|----------------|-------------------|
|  np.array  |    0.21656     |      0.16833      |
|------------|----------------|-------------------|

Gördüğünüz gibi 2 deney denedim - kullanarak np.random.rand(10000)ve np.random.rand(1, 10000) Ve eğer 2d dizileri kullanırsak np.stackve np.arrayek boyut yaratırsak - sonuç.shape (1,10000,10000) ve (10000,1,10000), bu yüzden bundan kaçınmak için ek eylemlere ihtiyaçları var .

Kod:

from time import perf_counter
from tqdm import tqdm_notebook
import numpy as np
l = []
for i in tqdm_notebook(range(10000)):
    new_np = np.random.rand(10000)
    l.append(new_np)



start = perf_counter()
stack = np.stack(l, axis=0 )
print(f'np.stack: {perf_counter() - start:.5f}')

start = perf_counter()
vstack = np.vstack(l)
print(f'np.vstack: {perf_counter() - start:.5f}')

start = perf_counter()
wrap = np.array(l)
print(f'np.array: {perf_counter() - start:.5f}')

start = perf_counter()
l = [el.reshape(1,-1) for el in l]
conc = np.concatenate(l, axis=0 )
print(f'np.concatenate: {perf_counter() - start:.5f}')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.