如何使NumPy数组的元素可设置属性?
我有一个Python对象的属性,它返回一个数组。现在,我可以设置这个属性的设置器,这样整个数组就可以被设置了。不过,我不太清楚如何让数组里的每个元素也能通过这个属性单独设置。
从用户的角度来看(假设有一个空的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
一切仍然像上面那样工作。如果我强制在设置器中使用简单的NumPy数组也是可以的。
但是,如果我把return self._a
替换成一个NumPy函数(这个函数会逐个处理元素),并把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
因为数组是可变对象,所以即使没有设置函数,我们也可以直接修改数组里的每个元素:
>>> 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])
这就是元组和列表的一个区别,列表是可变的,可以修改,而元组则不可修改。总之,回答你的问题:想要修改单个元素其实很简单,只要你的获取函数返回的是对象本身。
至于你第二个例子中的更复杂的性能,似乎没有简单的方法可以实现。我觉得你可以通过让你的 SomeClass.array
属性成为一个自定义类来实现这个功能,这个类要么是 ndarray
的子类,要么是它的一个实例的包装。不管哪种方式,都需要做不少的工作。