如何将numpy数组列表转换为单个numpy数组?

jucafojl  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(129)

假设我有;

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来说,它真的很慢
你认为最有效的方法是什么?

hyrbngr7

hyrbngr71#

通常,您可以沿沿着任何轴连接整个数组序列:

numpy.concatenate( LIST, axis=0 )

字符串
但是你需要考虑列表中每个数组的形状和维数(对于一个2维的3x 5输出,你需要确保它们都是2维的n-by-5数组)。如果你想把1维数组连接起来作为一个2维输出的行,你需要扩展它们的维数。
正如Jorge的回答所指出的,还有numpy 1.10中引入的函数stack

numpy.stack( LIST, axis=0 )


这是一种互补的方法:它为每个输入数组创建一个新的视图,并在连接之前添加一个额外的维度(在本例中,在左侧,因此每个n元素的一维数组变成一个1 × n的二维数组)。只有当所有输入数组都具有相同的形状时,它才有效。
vstack(或等价的row_stack)通常是一个可扩展的解决方案,因为它将接受一个一维和/或二维数组的序列,并在必要时自动扩展维度,并且只在必要时,在将整个列表连接在一起之前。如果需要新的维度,它将添加到左侧。同样,您可以一次连接整个列表而无需重新配置:

numpy.vstack( LIST )


语法快捷方式numpy.r_[ array1, ...., arrayN ]也展示了这种灵活的行为(注意方括号)。这对于连接几个显式命名的数组很好,但在您的情况下它变得不那么可读,因为[]下标将不接受list。您需要将您的序列转换为tuplenumpy.r_[tuple(LIST)]。简单地使用vstack()更具可读性。
还有一个类似的函数column_stack和快捷方式c_[...],用于水平(按列)堆叠,以及一个 * 几乎 * 类似的函数hstack-尽管由于某种原因后者不太灵活(它对输入数组的维度更严格,并试图将一维数组端到端连接,而不是将它们视为列)。
最后,在一维阵列的垂直堆叠的特定情况下,以下也起作用:

numpy.array( LIST )


.因为数组可以从其他数组的序列中构造出来,在开始处添加一个新的维度。

92dk7w1h

92dk7w1h2#

从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

字符串
好好享受,

brgchamk

brgchamk3#

我检查了一些方法的速度性能,发现**没有区别!**唯一的区别是,使用一些方法,你必须仔细检查尺寸。
时间:

|------------|----------------|-------------------|
|            | 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.stacknp.array创建额外的维度-结果。形状是(1,1000,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}')

f1tvaqid

f1tvaqid4#

另一个解决方案是使用asarray函数:
numpy.asarray(LIST)

koaltpgm

koaltpgm5#

我发现了一个更健壮的numpy函数reshape
stackvstack的问题是,它对空列表失败。

>>> LIST = [np.array([1, 2, 3, 4, 5]), np.array([1, 2, 3, 4, 5]),np.array([1,2,3,4,5])]
>>> s = np.vstack(LIST)
>>> s.shape
(3, 5)
>>> s = np.vstack([])
ValueError: need at least one array to concatenate

字符串
另一种选择是重塑

>>> s = np.reshape(LIST, (len(LIST),5))
>>> s.shape
(3, 5)
>>> LIST = []
>>> s = np.reshape(LIST, (len(LIST),5))
>>> s.shape
(0,5)


缺点是,您需要知道内部数组的长度/形状

相关问题