概括
我们知道,在python中,变量的赋值‘=’其实是对原始变量的引用,是一种绑定。因此有时我们为了创建新的变量而不影响原始数据,需要使用拷贝(copy),这也是赋值和拷贝的不同。
numpy中的索引有切片索引(slice array indexing)和整型索引(integer array indxing)
其中,numpy array中的切片索引(slice)是对原始数组的一个view,会影响原始数组的。而后者情况比较复杂,不过是basic indexing,则依然是原始数组的一个view,如果是advanced indexig,会用原始数组创建一个新的数组,不会影响原始数据。
x[1, 3:8], x[2:5, 6:9]是slice索引,而x[1,2]是基本integer索引, x[[1,2], [1,4]]是高级integer索引。
针对pytorch tensor可以通过data_ptr()查看第一个元素地址是否相同:
>>> t = torch.rand(4, 4)
>>> b = t.view(2, 8)
>>> t.storage().data_ptr() == b.storage().data_ptr() # `t` and `b` share the same underlying data.
True
# Modifying view tensor changes base tensor as well.
>>> b[0][0] = 3.14
>>> t[0][0]
tensor(3.14)
Pytorch中
更加详细的解释:https://pytorch.org/docs/stable/tensor_view.html
For reference, here’s a full list of view ops in PyTorch:
Basic slicing and indexing op, e.g.
tensor[0, 2:, 1:7:2]
returns a view of basetensor
, see note below.
view_as_real()
view_as_imag()
split_with_sizes()
indices()
(sparse tensor only)
values()
(sparse tensor only)It’s also worth mentioning a few ops with special behaviors:
reshape()
,reshape_as()
andflatten()
can return either a view or new tensor, user code shouldn’t rely on whether it’s view or not.
contiguous()
returns itself if input tensor is already contiguous, otherwise it returns a new contiguous tensor by copying data.
Numpy中
Pytorch的行为是模仿Numpy的,numpy提供了详细的说明,什么时候是view,什么时候是copy:
https://numpy.org/doc/stable/reference/arrays.indexing.html
Advanced indexing is triggered when the selection object, obj, is a non-tuple sequence object, an
ndarray
(of data type integer or bool), or a tuple with at least one sequence object or ndarray (of data type integer or bool). There are two types of advanced indexing: integer and Boolean.Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).
具体说明参加上面链接