[英]Subclassing numpy ndarray problem
我想继承numpy ndarray。 但是,我无法更改阵列。 为什么self = ...
不会改变阵列? 谢谢。
import numpy as np
class Data(np.ndarray):
def __new__(cls, inputarr):
obj = np.asarray(inputarr).view(cls)
return obj
def remove_some(self, t):
test_cols, test_vals = zip(*t)
test_cols = self[list(test_cols)]
test_vals = np.array(test_vals, test_cols.dtype)
self = self[test_cols != test_vals] # Is this part correct?
print len(self) # correct result
z = np.array([(1,2,3), (4,5,6), (7,8,9)],
dtype=[('a', int), ('b', int), ('c', int)])
d = Data(z)
d.remove_some([('a',4)])
print len(d) # output the same size as original. Why?
您没有得到预期结果的原因是因为您在方法remove_some
中重新分配self
。 您只是创建一个新的局部变量self
。 如果你的数组形状没有改变,你可以简单地做自我[:] = ...你可以保持对self
的引用,一切都会很好,但你正试图改变self
的形状。 这意味着我们需要重新分配一些新的内存,并在我们引用self
时改变我们所指向的位置。
我不知道该怎么做。 我认为可以通过__array_finalize__
或__array__
或__array_wrap__
来实现。 但我所尝试的一切都不尽如人意。
现在,还有另一种方法可以解决这个问题,而不是ndarray
子类。 你可以创建一个新的类来保存一个ndarray属性,然后覆盖所有通常的__add__
, __mul__
等。这样的事情:
Class Data(object):
def __init__(self, inarr):
self._array = np.array(inarr)
def remove_some(x):
self._array = self._array[x]
def __add__(self, other):
return np.add(self._array, other)
好吧,你明白了。 覆盖所有操作员是一种痛苦,但从长远来看,我认为更灵活。
你必须阅读这彻底把事情做对。 像__array_finalize__
这样的方法需要被称为正确的“清理”时间。
也许这是一个函数,而不是一个方法:
import numpy as np
def remove_row(arr,col,val):
return arr[arr[col]!=val]
z = np.array([(1,2,3), (4,5,6), (7,8,9)],
dtype=[('a', int), ('b', int), ('c', int)])
z=remove_row(z,'a',4)
print(repr(z))
# array([(1, 2, 3), (7, 8, 9)],
# dtype=[('a', '<i4'), ('b', '<i4'), ('c', '<i4')])
或者,如果你想要它作为一种方法,
import numpy as np
class Data(np.ndarray):
def __new__(cls, inputarr):
obj = np.asarray(inputarr).view(cls)
return obj
def remove_some(self, col, val):
return self[self[col] != val]
z = np.array([(1,2,3), (4,5,6), (7,8,9)],
dtype=[('a', int), ('b', int), ('c', int)])
d = Data(z)
d = d.remove_some('a', 4)
print(d)
这里的关键区别是remove_some
不会尝试修改self
,它只返回一个新的Data
实例。
我尝试做同样的事情,但是将ndarray子类化为非常复杂。
如果您只需要添加一些功能,我建议创建一个将数组存储为属性的类。
class Data(object):
def __init__(self, array):
self.array = array
def remove_some(self, t):
//operate on self.array
pass
d = Data(z)
print(d.array)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.