【问题标题】:How to create a dynamic array如何创建动态数组
【发布时间】:2011-10-20 11:55:33
【问题描述】:

据我了解,Python 中的list 类型是一个动态指针数组,它会在添加项目时增加它的容量。而 NumPy 中的数组使用一个连续的内存区域来保存数组的所有数据。

是否有任何类型可以动态增加其作为列表的容量,并将值存储为 NumPy 数组?类似于 C# 中的列表。如果该类型具有与 NumPy 数组相同的接口,那就太好了。

我可以创建一个类,在里面封装一个 NumPy 数组,并在这个数组满时调整它的大小,例如:

class DynamicArray(object):
    def __init__(self):
        self._data = np.zeros(100)
        self._size = 0

    def get_data(self):
        return self._data[:self._size]

    def append(self, value):
        if len(self._data) == self._size:
            self._data = np.resize(self._data, int(len(self._data)*1.25))
        self._data[self._size] = value
        self._size += 1

但DynamicArray不能用作NumPy数组,我认为在np.resize()之前get_data()返回的所有视图都会持有旧数组。

编辑:数组模块中的数组类型是动态数组。以下程序测试列表和数组的增加因子:

from array import array
import time
import numpy as np
import pylab as pl

def test_time(func):
    arrs = [func() for i in xrange(2000)]
    t = []
    for i in xrange(2000):
        start = time.clock()
        for a in arrs:
            a.append(i)
        t.append(time.clock()-start)
    return np.array(t)

t_list = test_time(lambda:[])
t_array = test_time(lambda:array("d"))
pl.subplot(211)
pl.plot(t_list, label="list")
pl.plot(t_array, label="array")
pl.legend()
pl.subplot(212)
pl.plot(np.where(t_list>2*np.median(t_list))[0])
pl.plot(np.where(t_array>2*np.median(t_array))[0])
pl.show()

从图中:list的增加因子大于array。

【问题讨论】:

  • 你知道 numpy 有一个 append 函数,对吧?它会创建数据的副本,然后您在上面使用的numpy.resize 也会创建数据副本。如果这不能满足您的要求,那么您能否再解释一下您为什么要这样做?
  • @senderle:是的,我知道 append 函数,但我需要一个动态数组,当它已满时,它的容量会增加 1.25 倍。

标签: python list numpy


【解决方案1】:

您可能有兴趣知道 Python 标准库还包含一个 array 模块,这听起来正是您想要的:

这个模块定义了一个对象类型,它可以紧凑地表示一个 基本值数组:字符、整数、浮点数。 数组是序列类型,其行为与列表非常相似,除了 存储在其中的对象的类型受到限制。

【讨论】:

  • 谢谢。我不知道数组有 append() 方法。如果 NumPy 中有类似的类型就好了,因为我想用 ufuncs 对这个动态数组进行计算。
  • @user772649,就其价值而言,array 的 append 方法并没有将其容量增加一倍——它恰好将其容量增加了一倍。同样,extend 方法通过添加的项目数来增加其容量。
  • @senderle,我通过测量它所花费的时间来测试数组的追加方法,因为调整数组大小会花费更多时间。我编辑了原始问题并添加了增加图。从图中可以看出,数组是按倍增加的,比列表要小。
  • @user772649,实际上,查看source code,我发现我错了——arrays 确实被过度分配了。对不起!我应该更频繁地检查源代码:)
猜你喜欢
  • 1970-01-01
  • 2015-07-15
  • 2015-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
相关资源
最近更新 更多