创建包含numpy数组子集的视图

创建包含numpy数组子集的视图,numpy,select,indexing,view,Numpy,Select,Indexing,View,我有一个numpy形状数组(1000100) 我想创建一个新数组,包含前100行,然后是第200行和第29行之间的所有行(包括边界)。有没有办法只使用视图,而不复制阵列的所有数据?不幸的是,没有 原因如下:NumPy数组从底层连续内存块中提取数据。 数组的数据类型、形状和步长决定了如何将该内存块中的数据解释为值 由于数组只能有一个“跨步数”属性,因此这些值必须有规则的间隔。因此,数组不能是以不规则间隔从原始数组中获取值的另一个数组的视图 但是,请注意,通过对3D阵列进行巧妙的重塑,可以将所需的值

我有一个numpy形状数组(1000100) 我想创建一个新数组,包含前100行,然后是第200行和第29行之间的所有行(包括边界)。有没有办法只使用视图,而不复制阵列的所有数据?

不幸的是,没有

原因如下:NumPy数组从底层连续内存块中提取数据。 数组的数据类型、形状和步长决定了如何将该内存块中的数据解释为值

由于数组只能有一个“跨步数”属性,因此这些值必须有规则的间隔。因此,数组不能是以不规则间隔从原始数组中获取值的另一个数组的视图

但是,请注意,通过对3D阵列进行巧妙的重塑,可以将所需的值视为具有规则间距跨步的切片。因此,如果您愿意添加另一个维度,则可以创建具有所需值的视图


基于Divakar的答案,您还可以使用
a.reformate(10,-1,a.shape[1])[:3:2]
。这会将数组分成10个块,然后将前3个块切掉,然后按2步进行操作——只给出第一个块和第三个块。

您可以拥有一个形状
(2100100)
的3D数组,其中第一个元素将是第一个块(0-99)行和第二个元素表示第二个块,其值从输入数组的200到299行

执行工作将是:-

a[:300].reshape(3,-1,a.shape[1])[::2]
使用shape
(20,5)
的输入数组运行示例,因为我们将尝试获取行
(0-5)
(10-15)
-

1) 输入阵列:

In [364]: a  
Out[364]: 
array([[6, 2, 3, 4, 7],
       [4, 7, 7, 4, 7],
       [3, 5, 6, 2, 1],
       [0, 6, 7, 4, 8],
       [1, 5, 8, 6, 7],
       [6, 3, 3, 3, 3],
       [1, 6, 1, 3, 5],
       [6, 8, 4, 7, 6],
       [8, 4, 6, 8, 7],
       [4, 8, 3, 5, 2],
       [4, 6, 7, 0, 8],
       [7, 1, 6, 0, 7],
       [1, 5, 5, 4, 4],
       [3, 4, 8, 4, 7],
       [0, 4, 5, 0, 5],
       [2, 6, 8, 2, 4],
       [5, 6, 2, 5, 0],
       [6, 2, 4, 2, 7],
       [3, 1, 6, 8, 4],
       [0, 4, 3, 2, 0]])
2) 使用建议的切片和重塑为我们提供一个3D阵列:

In [365]: a[:15].reshape(3,-1,a.shape[1])[::2] 
Out[365]: 
array([[[6, 2, 3, 4, 7],
        [4, 7, 7, 4, 7],
        [3, 5, 6, 2, 1],
        [0, 6, 7, 4, 8],
        [1, 5, 8, 6, 7]],

       [[4, 6, 7, 0, 8],
        [7, 1, 6, 0, 7],
        [1, 5, 5, 4, 4],
        [3, 4, 8, 4, 7],
        [0, 4, 5, 0, 5]]])
3) 通过手动切片验证输出:

In [366]: a[:5]
Out[366]: 
array([[6, 2, 3, 4, 7],
       [4, 7, 7, 4, 7],
       [3, 5, 6, 2, 1],
       [0, 6, 7, 4, 8],
       [1, 5, 8, 6, 7]])

In [367]: a[10:15]
Out[367]: 
array([[4, 6, 7, 0, 8],
       [7, 1, 6, 0, 7],
       [1, 5, 5, 4, 4],
       [3, 4, 8, 4, 7],
       [0, 4, 5, 0, 5]])
4) 最后,最重要的一点是验证它确实是一个视图:

In [368]: np.shares_memory(a, a[:15].reshape(3,-1,a.shape[1])[::2])
Out[368]: True
5) 当然,我们可以在之后对其进行重塑以获得2D输出,但这会强制在那里进行复制-

In [371]: a[:15].reshape(3,-1,a.shape[1])[::2].reshape(-1,a.shape[1])
Out[371]: 
array([[6, 2, 3, 4, 7],
       [4, 7, 7, 4, 7],
       [3, 5, 6, 2, 1],
       [0, 6, 7, 4, 8],
       [1, 5, 8, 6, 7],
       [4, 6, 7, 0, 8],
       [7, 1, 6, 0, 7],
       [1, 5, 5, 4, 4],
       [3, 4, 8, 4, 7],
       [0, 4, 5, 0, 5]])

In [372]: np.shares_memory(a, _)
Out[372]: False

如果形状
(2100100)
,其中形状
(100100)的第一个元素
将是第一个块和第二个相同形状的元素,表示原始数组中从200到299的第二个块?如果行数不能被块大小100整除,则必须小心。是的,这是真的。