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