目前,我有一些像这样的代码
import numpy as np
ret = np.array([])
for i in range(100000):
tmp = get_input(i)
ret = np.append(ret, np.zeros(len(tmp)))
ret = np.append(ret, np.ones(fixed_length))
我认为此代码效率不高,因为np.append
需要返回数组的副本而不是修改就地
我想知道我是否可以将extend
用于这样的numpy数组:
import numpy as np
from somewhere import np_extend
ret = np.array([])
for i in range(100000):
tmp = get_input(i)
np_extend(ret, np.zeros(len(tmp)))
np_extend(ret, np.ones(fixed_length))
这样extend
会更有效率。
有没有人有这个想法?
谢谢!
答案 0 :(得分:29)
想象一个numpy数组占用一个连续的内存块。现在想象一下其他对象,比如其他numpy数组,它们占用了我们numpy数组左右两侧的内存。没有空间可以附加或扩展我们的numpy数组。 numpy数组中的基础数据始终占用连续的内存块。
因此,任何追加或扩展我们的numpy数组的请求只能通过分配一个全新的更大内存块,将旧数据复制到新块然后追加或扩展来满足。
所以:
答案 1 :(得分:12)
您可以使用ndarrays的.resize()
方法。它要求内存不被其他数组/变量引用。
import numpy as np
ret = np.array([])
for i in range(100):
tmp = np.random.rand(np.random.randint(1, 100))
ret.resize(len(ret) + len(tmp)) # <- ret is not referred to by anything else,
# so this works
ret[-len(tmp):] = tmp
使用通常的阵列存储器叠加方案可以提高效率。
答案 2 :(得分:10)
处理此问题的常用方法是这样的:
import numpy as np
ret = []
for i in range(100000):
tmp = get_input(i)
ret.append(np.zeros(len(tmp)))
ret.append(np.zeros(fixed_length))
ret = np.concatenate(ret)
由于其他答案的原因,通常无法在不复制数据的情况下扩展数组。
答案 3 :(得分:0)
我在研究就地numpy插入方法时遇到了这个问题。
在阅读这里给出的答案时,我想到了另一种选择(也许是一个幼稚的想法,但仍然是一个主意):为什么不将numpy数组转换回列表,将想要添加的内容追加到列表中并将其转换回数组?
如果您需要完成许多插入操作,则可以创建一种“列表缓存”,在其中将所有插入内容放入并一步插入到列表中。
当然,如果要不惜一切代价避免转换为列表然后再返回为numpy,则不是一种选择。