Python 在numpy数组中处理类的属性

Python 在numpy数组中处理类的属性,python,class,numpy,attributes,Python,Class,Numpy,Attributes,我想处理类属性,而不必经过Python for循环。要处理大型数组,numpy是最好/最快的,但是否可以访问numpy数组中的类属性?考虑下面的简单化代码: import numpy as np class MyClass(): def __init__(self): self.myvar1 = 10 self.myvar2 = 20 myarray1 = np.arange(0, 1000, 1) myarray2 = np.array([MyCla

我想处理类属性,而不必经过Python for循环。要处理大型数组,numpy是最好/最快的,但是否可以访问numpy数组中的类属性?考虑下面的简单化代码:

import numpy as np

class MyClass():
    def __init__(self):
        self.myvar1 = 10
        self.myvar2 = 20

myarray1 = np.arange(0, 1000, 1)
myarray2 = np.array([MyClass() for i in range(1000)])
myarray1
的所有值都可以通过一行轻松修改:

myarray1 += 5
但是如何访问
myarray2
中所有
MyClass
实例的
myvar1
,并一次性修改它呢?(有可能吗?)我知道以下方法不起作用,但它给出了我想要实现的想法:

myarray2.myvar1 += 5
myarray2[myarray2.myvar1] += 5
我一直在四处寻找解决方案,我能找到的最接近的东西是numpy的recarray,它可以模拟Python类,但它似乎不是我的解决方案,因为我使用的类是一个子类(确切地说是pyglet Sprite),所以我确实需要使用Python类

编辑 继hpaulj comment之后,我尝试使用该类的向量化函数来更新其属性。这是更新类的所有实例的有效方法吗

class MyClass():
    def __init__(self):
        self.myvar1 = 10
        self.myvar2 = 20
    def modifyvar(self):
        self.myvar1 += 5
        return self

vecfunc = np.vectorize(MyClass.modifyvar)
myarray2 = np.array([MyClass() for i in range(1000)])
myarray2 = vecfunc(myarray2)
但是,另一个问题出现了:当使用此代码时,
myarray2[0]。myvar1
返回20而不是15
myarray2[1]。myvar1
返回15,数组的其余部分也返回15。为什么
myarray2[0]
在这里有所不同


解决方案 对类的函数进行矢量化可以在不使用for循环的情况下处理其多个实例的属性。解决方案的代码:

class MyClass():
    def __init__(self):
        self.myvar1 = 10
        self.myvar2 = 20
    def modifyvar(self):
        self.myvar1 += 5
        return self

vecfunc = np.vectorize(MyClass.modifyvar, otypes=[object])
myarray2 = np.array([MyClass() for i in range(1000)])
vecfunc(myarray2)

注意:在使用矢量化和处理对象时添加
otype=[object]

对第一个元素额外应用
modifyvar
是因为
vectorize
试图确定要返回的数组类型。指定
otypes
可以解决这个问题:

vecfunc = np.vectorize(MyClass.modifyvar,otypes=[object])
使用此“就地”修饰符,您无需注意返回的内容:

vecfunc(myarray2)
这就足够了

矢量化
文档:

通过调用 具有输入的第一个元素的函数。这是可以避免的 通过指定
otypes
参数

如果定义了
add5
方法,如:

    def add5(self):
        self.myvar1 += 5
        return self.myvar1
然后

将返回一个数字数组,同时修改
myarray2

array([15, 15, 15, 15, 15, 15, 15, 15, 15, 15])
要显示我使用的值,请执行以下操作:

[x.myvar1 for x in myarray2]
我真的应该定义一个矢量化的“打印”


这看起来像是
矢量化的更好应用之一。它不会给您任何编译速度,但它允许您在逐个操作实例时使用数组表示法和广播。例如
vecfunc(myarray2.Reformate(2,5))
返回一个
(2,5)
值数组。

是您希望避免For循环的唯一原因,因为您希望/期望没有For循环会更快?这是主要原因之一,但即使它不能提高性能,我仍然想知道是否可以访问numpy数组中对象的属性。
myarray2
具有
dtype=object
。因此,其数据缓冲区中的每个条目都是指向内存中其他位置的实例的指针。该类型数组的矢量化(使用编译代码)操作非常简单。
recarray
是结构化数组的覆盖。数据存储为恒定大小的“元组”(与数字或指针相反)。对于结构化数组,您可以使用
myarray3['myvar1']+=1
谢谢您的帮助。我不明白
recarray
如何一次更新所有python类实例,您能解释一下吗?对于矢量化操作,请查看我的编辑,并让我知道我的方向是否正确。非常好!与使用for循环相比,它可以工作,并且性能大大提高。谢谢:)可能夸大了它的性能,需要进一步测试。但这仍然是处理类的好方法——建议将实例属性存储在记录数组中,并动态创建实例以访问方法。
[x.myvar1 for x in myarray2]