追加numpy数组的有效方法

2024-05-01 21:43:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我会保持简单。我有一个循环,它将新行附加到numpy数组…什么是有效的方法来做这件事。

n=np.zeros([1,2])
for x in [[2,3],[4,5],[7,6]]
      n=np.append(n,x,axis=1)

现在问题是有一个[0,0]粘在上面,所以我必须通过

   del n[0]

看起来很蠢…所以请告诉我一个有效的方法。

   n=np.empty([1,2])

更糟糕的是,它会创建一个未初始化的值。


Tags: 方法innumpyfornpzeros数组empty
3条回答

“为什么列出”部分的一点技术解释。

在内部,一个长度未知的列表的问题是,不管其长度如何,它都需要以某种方式放入内存。基本上有两种不同的可能性:

  1. 使用数据结构(链表、一些树结构等),这样就可以为列表中的每个新元素分别分配内存。

  2. 将数据存储在连续的内存区域中。这个区域必须在创建列表时分配,并且必须大于我们最初需要的区域。如果列表中有更多的内容,我们需要尝试分配更多的内存,最好是在同一个位置。如果我们不能在同一个位置执行,我们需要分配一个更大的块并移动所有数据。

第一种方法可以实现各种各样的插入和删除选项、排序等。但是,它在顺序读取方面比较慢,并且分配了更多的内存。Python实际上使用方法2,列表存储为“动态数组”。有关详细信息,请参见:

Size of list in memory

这意味着使用append可以非常高效地设计列表。如果你事先不知道列表的大小,你就没什么办法加快速度。


如果您事先知道列表的最大大小,那么最好使用最大大小的numpy.empty(而不是numpy.zeros)来分配一个numpy.array,然后在填写完所有数据后使用ndarray.resize来收缩数组。

由于某些原因,numpy.array(l)(其中l是一个列表)对于大型列表来说通常速度很慢,而即使是大型数组的复制也非常快(我只是试图创建一个100000个元素数组的副本;它只花了不到0.5秒)。

这次讨论对不同的选择有更多的基准:

Fastest way to grow a numpy numeric array

我还没有对numpy.empty+ndarray.resize组合进行基准测试,但两者都应该是微秒操作,而不是毫秒操作。

有三种方法可以做到这一点,如果您已经在列表中列出了所有内容:

data = [[2, 3], [4, 5], [7, 6]]
n = np.array(data)

如果你知道最终的阵列有多大:

exp = np.array([2, 3])    

n = np.empty((3, 2))
for i in range(3):
    n[i, :] = i ** exp

如果您不知道最终数组的大小:

exp = np.array([2, 3])

n = []
i = np.random.random()
while i < .9:
    n.append(i ** exp)
    i = np.random.random()
n = np.array(n)

或者您可以以n = np.empty((0, 2))开头的记录,但我不建议在循环中追加到该数组。

您可能想尝试:

import numpy as np

n = np.reshape([], (0, 2))
for x in [[2,3],[4,5],[7,6]]:
      n = np.append(n, [x], axis=0)

您也可以使用n = np.vstack([n,x]),而不是np.append。我也同意@Bi Rico的观点,如果不需要在循环中访问n,我也将使用列表。

相关问题 更多 >