(numpy) __array_wrap__是做什么的?
讨论了关于ndarray
子类和钩子(如__array_wrap__
)的话题。np.array
接受copy
参数,即使其他方面不需要,也会强制结果为副本。 ravel
返回一个视图,而flatten
则返回一个副本。因此,可能可以构造一个ndarray
子类来强制复制,这可能涉及修改像__array_wrap__
这样的钩子。
或者可能修改.__getitem__
方法。像slice_of_arr = arr[0:6]
这样的索引涉及调用__getitem__
。对于ndarray
,这是编译的,但对于掩码数组,它是您可以用作示例的Python代码:
/usr/lib/python3/dist-packages/numpy/ma/core.py
这可能只是一些简单的东西。
def __getitem__(self, indx):
"""x.__getitem__(y) <==> x[y]
"""
_data = ndarray.copy(self, ndarray)
dout = ndarray.__getitem__(_data, indx)
return dout
我猜当你开发并完全测试这样的子类时,你可能会爱上默认的无复制方法。虽然这种视图与复制业务会影响许多新手(特别是从MATLAB转来的),但我没有看到有经验的用户抱怨。看看其他numpy SO问题;你不会看到很多copy()调用。
即使是常规的Python用户也习惯于问自己一个引用或切片是否为副本,以及某些东西是否可变。
例如,对于列表:
In [754]: ll=[1,2,[3,4,5],6]
In [755]: llslice=ll[1:-1]
In [756]: llslice[1][1:2]=[10,11,12]
In [757]: ll
Out[757]: [1, 2, [3, 10, 11, 12, 5], 6]
修改一个切片内部的项目将会修改原始列表中相应的项。与
numpy
相比,列表切片是副本,但是这是浅拷贝。您需要额外努力进行深拷贝(
import copy
)。
/usr/lib/python3/dist-packages/numpy/lib/index_tricks.py
包含一些旨在使某些索引操作更方便的索引函数。有几个实际上是类或类实例,具有自定义的
__getitem__
方法。它们还可以作为如何自定义切片和索引的模型。
matlab
中也没有相应的等价物。我必须要“记住”这种行为,而我真的不喜欢编程中的“重复”。 - ZK Zhao