将相同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=50j=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数组的两个视图组合成单个视图而不复制数组?的主要内容,如果未能解决你的问题,请参考以下文章

我如何在这里将两个模板视图合并到单个视图中?

将多个 numpy 数组组合成不同形状之一

用于将子行组合成单行视图的 SQL 查询

如何将两个每个 8 位的数组(二进制数字字符串组合成一个 16 位的单个字符串?(arduino,移位寄存器)

如何将两个firebase集合组合成一个新的对象数组

我可以使用 Kotlin 合成扩展让两个 xml 布局使用相同的视图吗?