如何创建一个不规则间隔的numpy数组切片的视图?

时间:2017-05-13 16:29:17

标签: python arrays numpy view

在以下情况中:

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}}切片的视图,那么会采用什么程序? 我考虑过创建一个掩码数组,但在文档中发现使用掩码数组进行复制。

换句话说,如果可能的话,我的目标是能够创建一个数组切片的视图,其中来自初始数组的索引不是有规律地间隔的。

1 个答案:

答案 0 :(得分:1)

数组的属性由shapestrides和数据组成。

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元素的唯一方法是挂在索引数组(或掩码)上,并在每次需要这些元素时应用它。