在以下情况中:
a = np.zeros(35)
# create a view
av = a[3:10]
assert np.may_share_memory(a, av)
some_ind = array([0,5,6,24])
# trying to create a second view of another slice of a
av2 = a[some_ind] # or a[np.where(some_ind)]
assert np.may_share_memory(a, av2) # raise AssertionError
如果av2
是对应于索引a
的{{1}}切片的视图,那么会采用什么程序?
我考虑过创建一个掩码数组,但在文档中发现使用掩码数组进行复制。
换句话说,如果可能的话,我的目标是能够创建一个数组切片的视图,其中来自初始数组的索引不是有规律地间隔的。
答案 0 :(得分:1)
数组的属性由shape
,strides
和数据组成。
a[3:10]
是一个视图,因为它可以使用原始数据缓冲区,只需在缓冲区中使用不同的形状(7,)和不同的起点。
a[some_ind]
无法成为视图,因为[0,5,6,24]
不是常规模式。它不能表示为形状,步幅和数据指针。必须拥有自己的数据副本。
In [534]: a=np.zeros(25,int)
In [535]: np.info(a)
class: ndarray
shape: (25,)
strides: (4,)
itemsize: 4
aligned: True
contiguous: True
fortran: True
data pointer: 0xafa5cc0
...
In [536]: np.info(a[3:10])
class: ndarray
shape: (7,)
strides: (4,)
itemsize: 4
aligned: True
contiguous: True
fortran: True
data pointer: 0xafa5ccc # ccc v cc0
....
In [537]: np.info(a[[0,5,6,24]])
class: ndarray
shape: (4,)
strides: (4,)
itemsize: 4
aligned: True
contiguous: True
fortran: True
data pointer: 0xae9c038 # different
...
或以十进制格式查看数据缓冲区指针:
In [538]: a.__array_interface__['data']
Out[538]: (184179904, False)
In [539]: a[3:10].__array_interface__['data']
Out[539]: (184179916, False) # 12 bytes larger
In [540]: a[[0,5,6]].__array_interface__['data']
Out[540]: (181099224, False)
另一种表达方式是:复制a
元素的唯一方法是挂在索引数组(或掩码)上,并在每次需要这些元素时应用它。