什么时候获取numpy数组的子矩阵返回视图但不复制? [英] When does getting submatrix of an numpy array returns view but not copy?

查看:90
本文介绍了什么时候获取numpy数组的子矩阵返回视图但不复制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取一个numpy二维数组的子矩阵,并对其进行修改.有时我会得到一个副本,对其进行的修改不会影响原始数组:

I'm trying to get a submatrix of a numpy 2D array, and modify it. Sometimes I get a copy, which modification to it does not affect the original array:

In [650]: d=np.random.rand(5,5)

In [651]: may_share_memory(d, d[[0,1],:][:,[2,3]])
Out[651]: False

In [652]: d[[0,1],:][:,[2,3]]=2

In [653]: d
Out[653]: 
array([[ 0.0648922 ,  0.41408311,  0.88024646,  0.22471181,  0.81811439],
       [ 0.32154096,  0.88349028,  0.30755883,  0.55301128,  0.61138144],
       [ 0.18398833,  0.40208368,  0.69888324,  0.93197147,  0.43538379],
       [ 0.55633382,  0.80531999,  0.71486132,  0.4186339 ,  0.76487239],
       [ 0.81193408,  0.4951559 ,  0.97713937,  0.33904998,  0.27660239]])

虽然有时may_share_memory还返回 False :

In [662]: d[np.ix_([0,1],[2,3])]=1

In [663]: d
Out[663]: 
array([[ 0.0648922 ,  0.41408311,  1.        ,  1.        ,  0.81811439],
       [ 0.32154096,  0.88349028,  1.        ,  1.        ,  0.61138144],
       [ 0.18398833,  0.40208368,  0.69888324,  0.93197147,  0.43538379],
       [ 0.55633382,  0.80531999,  0.71486132,  0.4186339 ,  0.76487239],
       [ 0.81193408,  0.4951559 ,  0.97713937,  0.33904998,  0.27660239]])

In [664]: may_share_memory(d, d[np.ix_([0,1],[2,3])])
Out[664]: False

更奇怪的是,如果将视图"分配给变量,它将变成副本"(同样,修改不会影响原始数组):

What more strange is, if assign that 'view' to a variable, it becomes a 'copy' (again, modification does not affect the original array):

In [658]: d2=d[np.ix_([0,1],[2,3])]

In [659]: may_share_memory(d,d2)
Out[659]: False

In [660]: d2+=1

In [661]: d
Out[661]: 
array([[ 0.0648922 ,  0.41408311,  0.88024646,  0.22471181,  0.81811439],
       [ 0.32154096,  0.88349028,  0.30755883,  0.55301128,  0.61138144],
       [ 0.18398833,  0.40208368,  0.69888324,  0.93197147,  0.43538379],
       [ 0.55633382,  0.80531999,  0.71486132,  0.4186339 ,  0.76487239],
       [ 0.81193408,  0.4951559 ,  0.97713937,  0.33904998,  0.27660239]])

推荐答案

您看到的是.

另外,为了清楚起见,d[np.ix_([0,1],[2,3])] = 1不是视图,而是分配.有关这方面的更多解释,请参见@EelcoHoogendoorn的答案.您感到困惑的根源似乎是Eelco谈到的__setitem__ vs __getitem__,但是我想我要添加一些具体的数字说明.

Also, for clarity, d[np.ix_([0,1],[2,3])] = 1 is not a view, it's an assignment. See @EelcoHoogendoorn's answer for more explanation in that regard. The root of your confusion seems to be with __setitem__ vs __getitem__, which Eelco addresses, but I thought I'd add a few numpy-specific clarifications.

每当您使用一系列坐标进行索引(np.ix_返回索引数组)时,它都是花哨的"索引,并且将始终返回副本.

Any time you index with a sequence of coordinates (np.ix_ returns an array of indicies), it's "fancy" indexing and will always return a copy.

您可以使用切片进行的所有操作始终返回视图.

Anything you can do with slicing with always return a view.

例如:

In [1]: import numpy as np

In [2]: x = np.arange(10)

In [3]: y = x[3:5]

In [4]: z = x[[3, 4]]

In [5]: z[0] = 100

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

In [6]: y[0] = 100

In [7]: x
Out[7]: array([  0,   1,   2, 100,   4,   5,   6,   7,   8,   9])

这样做的原因是numpy数组在内存中必须是半连续的(更确切地说,必须能够通过偏移量,步幅和形状来描述它们).

The reason for this is that numpy arrays have to be semi-contiguous in memory (more precisely, they have to be able to be described by an offset, strides, and shape).

任何类型的切片都可以用这种方式描述(甚至像x[:, 3:100:5, None]这样的东西).

Any type of slicing can be described this way (even something like x[:, 3:100:5, None]).

任意坐标序列(例如x[[1, 4, 5, 100]])不能是.

An arbitrary sequence of coordinates (e.g. x[[1, 4, 5, 100]]) cannot be.

因此,如果使用切片,则numpy始终返回一个视图,如果使用花式索引"(也就是使用一系列索引或布尔掩码),则numpy始终返回一个副本.

Therefore, numpy always returns a view if slicing is used and a copy if "fancy indexing" (a.k.a. using a sequence of indicies or a boolean mask) is used.

赋值(例如x[blah] = y)将总是就地修改numpy数组.

Assignments (e.g. x[blah] = y), however, will always modify a numpy array in-place.

这篇关于什么时候获取numpy数组的子矩阵返回视图但不复制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆