自定义类中的Numpy数组与列表的区别

3

我理解为什么存储"标准"类型的numpy数组几乎总比包含相同数据类型的列表更有效率。因此,养成使用numpy数组处理简单问题的习惯是更好的选择,对吗?

但是,与使用列表相比,我想知道将自定义类实例“存储”到numpy数组中使用的优缺点是什么。

请考虑以下内容:

import numpy as np

class Foo:
    def __init__(self, name):
        self.name = name

class Bar:
    def __init__(self, name):
        self.name = name
        self.myFoos = np.zeros(0, dtype = Foo)

    def add_foo(self, some_foo):
        self.myFoos = np.append(self.myFoos, some_foo)

我可以很好地使用

self.myFoos = []

在做出这个决定时,我应该注意什么?

Foo类的复杂性是否会有很大的影响? (在我的用例中,它包含大约20到30个标准类型,一两个固定大小的整数数组,然后大约10个简单的方法。)

myFoos中通常有多少个Foos是否会有影响? (在我的用例中,它将是零到十个)

myFoos被处理的次数是否会有影响? (在我的实际用例中,在用户操作之间可能会被调用10到20次。)

附:虽然代码运行良好,但pyCharm不喜欢最后一个append语句,它警告我:

Expected type 'Union[ndarray, iterable]' got 'Foo' instead.

提前致谢!


dtype=Foo 并不是你想象中的那样。 - user2357112
“最好养成使用numpy数组处理简单任务的习惯,除非我要进行适合numpy的计算,否则通常会从标准库容器开始,除非遇到性能问题才会寻找更好的解决方案。” - wwii
1个回答

7

我之前已经讨论过如何创建自定义对象的数组 - 我会尝试找到一个好的讨论。

但首先需要注意以下几点:

np.zeros(0, dtype = Foo)

这段代码 np.zeros(0, dtype=object) 实际上是创建一个空的数组。有一些标准的数据类型,还有一个名为object的类型。它可以存储指向内存中其他对象的指针。和列表类似,可以存储任何类型的数据 - 数字、字符串、列表、数组、Foo()None等,并且可以修改。

如果想要创建一个新的数组并将其他数组合并在一起,应该学会使用concatenate,而不是使用np.append替代列表追加操作。记住要确保维度匹配。

self.myFoos = np.append(self.myFoos, some_foo)

对象数据类型列表与普通列表基本相同,唯一不同的是它们可以重塑为2D数组,并且无法使用append方法增加长度。对于对象数据类型数组的许多操作都需要使用列表推导。


用类实例替换数组中的元素

将类实例的输出传递给另一个实例作为输入

我回答了这位提问者的几个问题(在同一时间段进行搜索),他们试图使用自定义类的数组。即使只是访问此类对象的属性也需要使用列表推导。


非常感谢@hpaulj!对我来说,收获如下:
  1. 如果我不需要将其重塑为2D(我没有),那么使用对象类型数组并不比使用列表更具优势。
  2. 远离np.append。学习使用concatenate。
那么,数组的声明并没有指定特定的类类型 - 只有对象类型?
- levraininjaneer

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