Załóżmy, że mam;
LIST = [[array([1, 2, 3, 4, 5]), array([1, 2, 3, 4, 5],[1,2,3,4,5])] # inner lists are numpy arrays
Próbuję się nawrócić;
array([[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5])
Rozwiązuję to teraz przez iterację na vstack, ale jest to bardzo powolne dla szczególnie dużej LISTY
Co sugerujesz, aby uzyskać najlepszy sposób?
LIST = [[array([1, 2, 3, 4, 5]), array([1, 2, 3, 4, 5],[1,2,3,4,5])]
to nie jest poprawna składnia Pythona. Proszę o wyjaśnienie.Odpowiedzi:
Ogólnie rzecz biorąc, można łączyć całą sekwencję tablic wzdłuż dowolnej osi:
numpy.concatenate( LIST, axis=0 )
ale nie trzeba się martwić o kształcie i wymiarowości każdej tablicy na liście (dla 2-wymiarowej wyjście 3x5, trzeba upewnić się, że wszyscy są 2-wymiarowe n-by-5 tablice już). Jeśli chcesz połączyć jednowymiarowe tablice jako wiersze dwuwymiarowego wyniku, musisz rozszerzyć ich wymiarowość.
Jak wskazuje odpowiedź Jorge, istnieje również funkcja
stack
, wprowadzona w numpy 1.10:numpy.stack( LIST, axis=0 )
Przyjmuje to podejście komplementarne: tworzy nowy widok każdej tablicy wejściowej i dodaje dodatkowy wymiar (w tym przypadku po lewej stronie, więc każda
n
-elementowa tablica 1D staje się tablicą 1-na-n
2D) przed połączeniem. Będzie działać tylko wtedy, gdy wszystkie tablice wejściowe mają ten sam kształt - nawet wzdłuż osi konkatenacji.vstack
(lub równoważnierow_stack
) jest często łatwiejszym w użyciu rozwiązaniem, ponieważ wymaga sekwencji jedno- i / lub dwuwymiarowych tablic i automatycznie rozszerza wymiarowanie w razie potrzeby i tylko w razie potrzeby, przed połączeniem całej listy razem. Tam, gdzie wymagany jest nowy wymiar, jest on dodawany po lewej stronie. Ponownie możesz połączyć całą listę naraz bez konieczności iteracji:To elastyczne zachowanie jest również widoczne w skrócie składniowym
numpy.r_[ array1, ...., arrayN ]
(zwróć uwagę na nawiasy kwadratowe). Jest to dobre do konkatenacji kilku jawnie nazwanych tablic, ale nie jest dobre w twojej sytuacji, ponieważ ta składnia nie akceptuje sekwencji tablic, takich jak twojaLIST
.Istnieje również analogiczna funkcja
column_stack
i skrótc_[...]
do układania poziomego (kolumnowego), a także funkcja prawie analogowa -hstack
chociaż z jakiegoś powodu ta ostatnia jest mniej elastyczna (jest bardziej rygorystyczna w kwestii wymiarowania tablic wejściowych i próbuje łączyć Tablice 1-w od końca do końca zamiast traktować je jako kolumny).Wreszcie, w szczególnym przypadku pionowego układania w stos tablic 1-D, działa również:
... ponieważ tablice można zbudować z sekwencji innych tablic, nadając początekowi nowy wymiar.
źródło
Począwszy od wersji NumPy 1.10, mamy stos metod . Może układać w stosy tablice o dowolnym wymiarze (wszystkie równe):
# 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
Cieszyć się,
źródło
Sprawdziłem niektóre metody szybkości działania i stwierdziłem, że nie ma różnicy! Jedyna różnica polega na tym, że przy użyciu niektórych metod należy dokładnie sprawdzić wymiar.
Wyczucie czasu:
|------------|----------------|-------------------| | | 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 | |------------|----------------|-------------------|
Jak widać, wypróbowałem 2 eksperymenty - używając
np.random.rand(10000)
inp.random.rand(1, 10000)
A jeśli użyjemy tablic 2d niżnp.stack
inp.array
utworzymy dodatkowy wymiar - result.shape to (1,10000,10000) i (10000,1,10000), więc potrzebują dodatkowych działań, aby tego uniknąć .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}')
źródło