将相同numpy数组的两个视图组合成单个视图而不复制数组?
Posted
技术标签:
【中文标题】将相同numpy数组的两个视图组合成单个视图而不复制数组?【英文标题】:Combining two views of same numpy array into single view without copying the array? 【发布时间】:2018-05-14 12:17:23 【问题描述】:我有一个大型 2d numpy 数组,我想删除它的子集并处理函数的剩余部分。我需要对许多子集执行此操作,因此理想情况下我不想每次都创建数组的副本。该函数不会更改数组中的任何值。
mat = np.load(filename)
mat_1 = mat[:i,:]
mat_2 = mat[j:,:]
到目前为止,mat_1 和 mat_2 是视图。 那我就想做
mat_s = np.concatenate((mat_1,mat_2))
result = func(mat_s)
但没有复制。这可能吗?
【问题讨论】:
你为什么不直接使用mat[j:i,:]
?
@Kasramvd 这与他正在做的事情不同。想想(100, 1)
与i=50
和j=20
的形状数组。生成的 np.concatenate
会创建一个重叠的结果数组,而您的 mat[j:i,:]
不会。
应该指定,但 j 大于 i。那只会返回一个空数组。
啊哈,所以如果j > i
,那么np.concatenate
不会创建重叠数组,而是连接两个分离的数组。 Kasramvd 的解决方案仍然不起作用。 filippo 已经展示了解决这个问题的好方法。
@filippo 是的,没错,它实际上会重复一些行。
【参考方案1】:
由于只能使用一组固定的strides
创建内存视图,因此您必须根据自己的情况创建一个副本,其中mat.shape[0] > j > i
。
这意味着只有当你想查看数组中的每个第 x 个元素时,视图才会起作用:
mat = np.arange(20)
view = mat[slice(0, 20, 4)]
view
# Out[41]: array([ 0, 4, 8, 12, 16])
所以这只适用于等间距单元格的视图。但是,如果您想查看一个连续的slice(0, i)
和另一个连续的slice(j, mat.shape[0])
,它就行不通。您必须复制一份。
【讨论】:
谢谢!我没想到要提它,但是数组中元素的顺序并不重要,所以这很好用。 太好了,很高兴能帮上忙!【参考方案2】:您可以删除要删除的行并将其直接传递给函数
mat = np.load(filename)
mat_s = np.delete(mat,list(range(i,j)),axis=0)
您可以通过添加范围列表来删除 2 个差异子集,例如
mat_s = np.delete(mat,list(range(i,j))+list(range(k,l)),axis=0)
上面删除行 i:j 和 k:l
【讨论】:
此方法还返回数组的副本。以上是关于将相同numpy数组的两个视图组合成单个视图而不复制数组?的主要内容,如果未能解决你的问题,请参考以下文章