Numpy数组内存问题

5

我认为我在使用numpy数组时遇到了内存问题。以下代码已经运行了数小时:

    new_data = npy.array([new_x, new_y1, new_y2, new_y3])
    private.data = npy.row_stack([private.data, new_data])

其中,new_x、new_y1、new_y2和new_y3均为浮点数。

每秒记录这些数据约5小时后(超过72000个浮点数),程序变得无响应。我认为发生了某种realloc和复制操作,导致进程被淹没。有人知道这是否是发生的情况吗?

我需要一种方法来记录这些数据,而不会遇到这个减速问题。没有办法事先大致知道这个数组的大小。它不一定需要使用numpy数组,但需要类似的东西。有人知道一个好的方法吗?

2个回答

3

使用Python列表。它们能更有效地增长。这就是它们的设计目的。在这种情况下,它们非常高效。

如果您最终需要将它们转换为数组(或甚至偶尔在计算过程中),先在列表中累加会更有效率。


2

更新: 我已经将@EOL的优秀索引建议纳入答案中。

问题可能在于row_stack增加目标数组的方式。您最好自己处理重新分配。以下代码分配了一个大的空数组,填充它,并随着每小时填充而增长。

numcols = 4
growsize = 60*60 #60 samples/min * 60 min/hour
numrows = 3*growsize #3 hours, to start with
private.data = npy.zeros([numrows, numcols]) #alloc one big memory block
rowctr = 0
while (recording):
    private.data[rowctr] = npy.array([new_x, new_y1, new_y2, new_y3])
    rowctr += 1
    if (rowctr == numrows): #full, grow by another hour's worth of data
        private.data = npy.row_stack([private.data, npy.zeros([growsize, numcols])])
        numrows += growsize

这样可以避免内存管理器过度抖动。我在每次迭代中尝试了使用row_stack,但使用此方法运行速度快了几个数量级。


好主意。npy.emptynpy.zeros更合适(而且可能稍微快一点)。 - Eric O. Lebigot
这真的很快。将其封装在一个具有row_stack方法的类中会很好。 - Eric O. Lebigot
1
请注意,private.data[rowctr] = …[rowctr, :]快得多。 - Eric O. Lebigot
@EOL - 感谢您的建议!我没有意识到您可以一次索引整行。而且这样做速度更快。 - mtrw
在我的测试中,似乎 npy.zerosnpy.empty 稍微快一点(约3%),所以我又改回前者了。但是你建议的索引更改却使速度提高了20%。 - mtrw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接