如何使NumPy数组属性的元素可设置?

时间:2014-07-22 14:40:17

标签: python arrays numpy properties

我有一个返回数组的Python对象的属性。 现在,我可以设置该属性的setter,以便整个数组可以设置。 但是,我错过了如何通过属性自行设置元素。

我希望从用户角度(给定一个空的SomeClass类):

>>> x = SomeClass()
>>> x.array = [1, 2, 3]
>>> x.array[1] = 4
>>> print (x.array)
[1, 4, 3]

现在,假设SomeClass.array是定义为

的属性
class SomeClass(object):
    def __init__(self, a):
        self._a = a

    @property
    def array(self):
        return self._a
    @array.setter
    def array(self, a):
        self._a = a

一切仍然如上所述。如果我在setter上强制使用简单的NumPy数组。

但是,如果我用NumPy函数替换return self._a(通过元素以矢量化方式)并且用反函数替换self._a = a,当然条目不会被设置了。

示例:

import numpy as np

class SomeClass(object):
    def __init__(self, a):
        self._a = np.array(a)

    @property
    def array(self):
        return np.sqrt(self._a)
    @array.setter
    def array(self, a):
        self._a = np.power(a, 2)

现在,用户看到以下输出:

>>> x = SomeClass([1, 4, 9])
>>> print (x.array)
array([1., 2., 3.])
>>> x.array[1] = 13
>>> print (x.array)    # would expect an array([1., 13., 3.]) now!
array([1., 2., 3.])

我想我理解问题的来源(NumPy在操作期间创建的数组会改变其元素,但它对存储的数组没有影响)。

SomeClass的正确实现是什么才能使数组的单个元素可以单独写入并因此可以设置?

非常感谢你的提示和帮助, TheXMA

@Jaime在他的回答下面提出的观点对我帮助很大!谢谢!

1 个答案:

答案 0 :(得分:0)

由于数组是可变对象,因此即使没有setter函数,各个项也可以设置:

>>> class A(object):
...     def __init__(self, a):
...         self._a = np.asarray(a)
...     @property
...     def arr(self):
...         return self._a
...
>>> a = A([1,2,3])

>>> a.arr
array([1, 2, 3])

>>> a.arr = [4,5,6] # There is no setter...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

>>> a.arr[1] = 7 # ...but the array is mutable
>>> a.arr
array([1, 7, 3])

这是元组与列表的一种用法,因为后者是可变的,但前者不是。无论如何,要回答你的问题:只要你的getter返回对象本身,使单个项目可设置很容易。

你的第二个例子中的发烧友表现似乎并不容易以任何简单的方式获得。我认为你可以通过使你的SomeClass.array属性成为一个自定义类,子类ndarray或包装它的实例来实现它。无论哪种方式都会有很多重要的工作。