如何将实例属性链接到numpy数组?

3
我有一个Python对象列表,代表了几个类。这些类显然不同,但仍然具有一些共同的属性(每个对象的值都不同)。例如:
class Super1:
    def __init__(self, value1, value2):
        self.value1 = value1
        self.value2 = value2
        #Lot's of other stuff

class Sub1(Super1):
    def __init__(self, value1, value2, value3):
        Super1.__init__(self, value1, value2)
        self.value3 = value3
        #Lot's of stuff

class Sub2(Super1):
    def __init__(self, value1, value2, value4):
        Super1.__init__(self, value1, value2)
        self.value4 = value4
        #Lot's of stuff

objects = [Sub1(1.,2.,3.), Sub1(213.,2.,23.), Sub2(23.,10.,0.2), Sub1(3.,2.,12.)]

现在,为了方便和提高性能,我需要将所有这些值转换成NumPy数组。我知道可以像这样读取它们:

np.array([objects[ii].value1 for ii in range(4)])

但我还需要改变值,既可以在数组形式中,也可以在实例方法中单独进行更改。是否可能通过使用指针或其他方式动态地将对象属性和对应的数组值进行 链接

而且,这里的对象不一定是列表。欢迎提出建议。


这是一个物理模型,对象代表不同的物理对象。我计划使用numpy,因为我需要对这些值执行矩阵代数运算。 - HenriV
为什么不使用np.array([o.value1 for o in objects]) - Benjamin Hodgson
好的,但这并没有解决实际问题... - HenriV
2个回答

4
Numpy数组是计算机内存中"连续的一维数据段",因此你无法创建由此处和那里的内存块组成的numpy数组。
唯一的可能性是反过来,先创建数组,然后将该数组的单个元素切片分配给你的对象,例如:
class Super1(object):
    def __init__(self, value1):
        self._value1 = value1

    @property
    def value1(self):
        return self._value1[0]

    @value1.setter
    def value1(self, value):
        self._value1[0] = value

现在:

>>> a = np.arange(4)
>>> obj = [Super1(a[j:j+1]) for j in xrange(len(a))]
>>> obj[0].value1
0
>>> obj[0].value1 = 5
>>> a
array([5, 1, 2, 3])
>>> obj[2].value1
2
>>> a[2] = 8
>>> obj[2].value1
8

太好了,就是这样!谢谢!为了记录,为了让你的代码正常工作,我不得不从构造函数中删除参数 value2,并在 return 命令中添加 self。 - HenriV
@HenriV 哎呀!我不得不自己更改那两个,才能让代码正常工作,忘记把更正后的代码粘贴在这里了。 - Jaime

1
如果您想修改对象的属性设置,请使用Properties。
此解决方案适用于数组的索引。
class Super(object):

    @property
    def value1(self):
        return self.array1[self.index]

    @value1.setter
    def value1(self, value):
        self.array1[self.index] = value

    def __init__(self, array1, index):
        self.array1 = array
        self.index = index

你需要先创建数组,然后再创建对象。
这是另一种使用一个数组来存储对象的解决方案:
class Super(object):

    @property
    def value1(self):
        return self.array[0]

    @value1.setter
    def value1(self, value):
        self.array[0] = value

    def __init__(self, array):
        self.array = array

我不确定我是否理解正确,但我认为我实现了你的第二个解决方案,而numpy数组中的更改不会反映在实例属性中,反之亦然...? - HenriV

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