【问题标题】:How to extract values of numpy array of a customized type more efficiently?如何更有效地提取自定义类型的numpy数组的值?
【发布时间】:2021-04-12 01:29:41
【问题描述】:

假设我已经定义了一个数据类型,如下:

class mytype(object):
    def __init__(self, x=1, y=2, z=3):
        self.x = x
        self.y = y 
        self.z = z 

我有一个 mytype 类型的 numpy 数组,定义为:

my_array = np.array([mytype()]*1000)

我的问题是:如何提取上面定义的 numpy 数组的值并将其设置为 np.float64 类型的 numpy 数组更有效?我发现当数组很大时使用列表理解非常慢,我想一定有一些好的方法来完成这项工作。谁能帮帮我

【问题讨论】:

  • 如果您想要 numpy 速度,请创建一个 (1000,3) 形状的浮点数组,或者可能是具有 3 个字段的结构化数组。带有objects 的数组比列表好一点,也许更糟。
  • [mytype()]*1000) 创建一个包含 1000 个对同一对象的引用的列表。尝试修改一个,看看我的意思。

标签: python numpy optimization


【解决方案1】:

Numpy 速度很快,因为它几乎是在 C 数组上运行计算的纯 C 代码。由于 C 数组,东西需要整洁;比如我们使用了多少空间?该空间的物体大小是多少?我们有多少物体?等当您创建任意 python 对象的集合(可以具有动态大小)然后想要获取该对象集合并将其放入 numpy 数组中时,需要找到并转换每个对象,并且没有'无论如何都不是。

my_array = np.array([mytype() for _ in range(1000)])

这基本上是 1000 个指向任意对象的指针。 Numpy 对这些对象一无所知,除了在哪里向 python 询问有关这些对象的更多信息。因此,上面的数组没有 C 代码来加速这个过程。它几乎相当于一个列表:

my_array = [mytype() for _ in range(1000)]

如果你想让你的代码更快,你不应该用任意对象创建 numpy 数组。同样,当你真的想要 float64 时,你不应该使用 python 整数(可以是任何大小并且有很多开销)。例如,您的课程可以更新:

class mytype(object):
    def __init__(self, x=1, y=2, z=3):
        self.data = np.array([x,y,z],dtype='float64')

至少现在每个 self.data 都可以被访问和 hstacked,并且由于 numpy 知道每个对象的确切大小和形状,因此 numpy 可能会收集内存中的所有 1000 个位置并很快将它们复制到一个新数组中.

【讨论】:

    【解决方案2】:

    基于 Numpy 文档 herenumpy.array 调用对象的 __array__ 方法。因此,您可以将任意转换定义为 numpy.array,例如:

    class mytype(object):
        def __init__(self, x=1, y=2, z=3):
            self.x = x
            self.y = y 
            self.z = z 
    
        def __array__(self):
            return np.array([self.x, self.y, self.z])
    

    然后您可以通过以下方式将单个 mytype() 对象转换为 np.array

    tmp = mytype()
    np.array(tmp)
    # array([1, 2, 3])
    

    现在,当您拥有 1000 个对象的列表时,您可以将 np.array 映射到所有对象:

    new_list = list(map(np.array, [mytype()]*1000))
    #[array([1, 2, 3]), array([1, 2, 3]), array([1, 2, 3]), array([1, 2, 3]), ...
    

    【讨论】:

      猜你喜欢
      • 2015-07-30
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 2019-08-26
      相关资源
      最近更新 更多