numpy在用python传统的slicing做index,和其自定义的numpy.array/list做index时的表现不同,非常坑人。。。
翻译自此文档:https://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html
- 什么是fancy index:详见numpy文档 。简单的说,除了传统的slicing(即
start:end:step
),只有可解释为slicing的tuple(如a[(1,2)] == a[1,2]
in numpy) 不是fancy index。tuple的例子还有a[(1:-1,2)]
和a[(1, Ellipsis, 1)] == a[1,...,1]
不是fancy index,而a[(1,2),]
则是fancy index了(因为无法解释为传统slicing)。 - fancy index和传统index的输出大不同:fancy index输出的是copy,而传统index输出的是view。还需声明的是,此不同仅存在在
__getattr__()
中,__setattr__()
不需要生成view/copy,故不存在此区别
下面是一个著名的例子:
>> a = numpy.arange(12).reshape(3,4)
>>> ifancy = [0,2]
>>> islice = slice(0,3,2)
>>> a[islice, :][:, ifancy] = 100
>>> a
array([[100, 1, 100, 3],
[ 4, 5, 6, 7],
[100, 9, 100, 11]])
>>> a = numpy.arange(12).reshape(3,4)
>>> ifancy = [0,2]
>>> islice = slice(0,3,2)
>>> a[ifancy, :][:, islice] = 100 # note that ifancy and islice are interchanged here
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
- view和copy的区别:网上资料很多,简单地说就是view是share memory即data的;而copy是不share的,完全独立于原始数据的。