numpy 배열 목록을 단일 numpy 배열로 변환하는 방법은 무엇입니까?


103

내가 가지고 있다고 가정하십시오;

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

나는 개종하려고 노력한다.

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

지금은 vstack에서 반복하여 해결하고 있지만 특히 큰 LIST의 경우 정말 느립니다.

가장 효율적인 방법을 위해 무엇을 제안합니까?


5
LIST = [[array([1, 2, 3, 4, 5]), array([1, 2, 3, 4, 5],[1,2,3,4,5])]이것은 올바른 파이썬 구문이 아닙니다. 명확히하십시오.
Marcin

답변:


131

일반적으로 모든 축을 따라 배열의 전체 시퀀스를 연결할 수 있습니다.

numpy.concatenate( LIST, axis=0 )

하지만 당신 목록에있는 각 배열의 모양과 차원에 대해 걱정할 필요 있습니다 (2 차원 3x5 출력의 경우 모두 2 차원 nx5 배열인지 확인해야합니다). 1 차원 배열을 2 차원 출력의 행으로 연결하려면 차원을 확장해야합니다.

Jorge의 답변이 지적했듯이 stacknumpy 1.10에 도입 된 함수도 있습니다 .

numpy.stack( LIST, axis=0 )

이것은 보완적인 접근 방식을 취합니다. 각 입력 배열의 새 뷰를 만들고 연결하기 전에 추가 차원 (이 경우 왼쪽에 있으므로 각 n요소 1D 배열이 1x2D 배열이 됨 n)을 추가합니다. 모든 입력 배열의 모양이 연결 축을 따라도 동일한 경우에만 작동합니다.

vstack(또는 동등하게 row_stack) 1 차원 및 / 또는 2 차원 배열의 시퀀스를 사용하고 전체 목록을 함께 연결하기 전에 필요한 경우에만 자동으로 차원을 확장하므로 사용하기 쉬운 솔루션입니다. 새 차원이 필요한 경우 왼쪽에 추가됩니다. 다시 말하지만, 반복 할 필요없이 전체 목록을 한 번에 연결할 수 있습니다.

numpy.vstack( LIST )

이 유연한 동작은 구문 단축키 numpy.r_[ array1, ...., arrayN ](대괄호에주의)에서도 나타납니다. 이것은 명시 적으로 명명 된 몇 개의 배열을 연결하는 데 유용하지만이 구문은 LIST.

수평 (열 단위) 스택과 거의 유사한 기능을위한 유사한 기능 column_stack과 단축키도 있습니다.c_[...]hstack 후자는 덜 유연 어떤 이유로 - 비록은 (는 입력 배열 '차원에 대해 엄격하고 연결하는 시도 1D 배열을 열로 처리하는 대신 종단 간 배열).

마지막으로, 1-D 배열의 수직 스택의 특정 사례에서 다음도 작동합니다.

numpy.array( LIST )

... 배열은 다른 배열의 시퀀스로 구성되어 시작 부분에 새로운 차원을 추가 할 수 있기 때문입니다.


5
나는 그가 2D 배열을 출력으로 원했다고 생각합니다.
Beefster

7

NumPy 버전 1.10부터는 stack 메소드가 있습니다 . 모든 차원 (모두 동일)의 배열을 스택 할 수 있습니다.

# 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

즐겨,


1

속도 성능에 대한 몇 가지 방법을 확인한 결과 차이가 없음을 알았습니다 ! 유일한 차이점은 몇 가지 방법을 사용하여 치수를주의 깊게 확인해야한다는 것입니다.

타이밍:

|------------|----------------|-------------------|
|            | 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      |
|------------|----------------|-------------------|

보시다시피 두 가지 실험을 시도했습니다-사용 np.random.rand(10000)np.random.rand(1, 10000) 2d 배열을 사용 np.stack하고 np.array추가 차원을 생성 하는 경우 -result.shape는 (1,10000,10000) 및 (10000,1,10000)이므로이를 피하기 위해 추가 작업이 필요합니다. .

암호:

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}')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.