numpy-为什么在某些情况下可以查看Z [(0,2)]而在其他情况下可以复制Z [(0,2)]? [英] numpy - why Z[(0,2)] can be view for some cases and be copy in the others?

查看:76
本文介绍了numpy-为什么在某些情况下可以查看Z [(0,2)]而在其他情况下可以复制Z [(0,2)]?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

继续问题 numpy-为什么Z [(0,2)]是视图而Z [(0,2),(0)]是副本?.我得到了答案,并理解逗号触发高级索引会产生完全不同的索引.答案还提供了一种使用 __ array_interface __ 来理解复制/查看行为的方法.

但是,显然,我还没有深入到答案的这一部分.

如果可以用形状,步幅以及原始数据缓冲区的全部或一部分来描述新数组,则返回视图.

因为我仍然无法解释以下行为为何不同.因此,提出了一个新问题,以深入了解这种(形状,步幅)机制,以了解视图/复制的工作原理.

请详细说明numpy如何使用 shhape stride 来确定是否返回副本.

第一个索引 X [0,1] 返回一个视图.

  X = np.arange(36).reshape(3、3、4)print("X为\ n {} \ n" .format(X))打印("X .__ array_interface__ \ n {} \ n" .format(X .__ array_interface__))_x = X [0,2个]print("X [0,1]是\ n {} \ n是视图吗?{} \ n" .format(_X,_x.base不是None))print("_ x .__ array_interface__是\ n {} \ n" .format(_x .__ array_interface__))---X是[[[0 1 2 3][4 5 6 7][8 9 10 11]][[12 13 14 15][16 17 18 19][20 21 22 23][[24 25 26 27][28 29 30 31][32 33 34 35]]X .__ array_interface__{'data':(94194168544480,False),'strides':None,'descr':[('','< i8')],'typestr':'< i8','shape':(3,3,4),'version':3}X [0,1]是[8 9 10 11]是视图吗?真的_x .__ array_interface__是{'data':(94194168544544,False),'strides':None,'descr':[('','< i8')],'typestr':'< i8','shape':(4,),版本":3} 

但是,下一个具有相同 [0,1] 的索引将返回一个副本.

  Y = np.arange(12).reshape(3,4)print("Y为\ n {} \ n" .format(Y))print("Y .__ array_interface__是\ n {} \ n" .format(Y .__ array_interface__))_y = Y [0,1个]print("Y [0,1]是\ n {} \ n是视图{} \ n" .format(_y,_y.base不是None))print(.Y [0,1] .__ array_interface__是\ n {} \ n" .format(_y .__ array_interface__))---Y是[[0 1 2 3][4 5 6 7][8 9 10 11]]Y .__ array_interface__是{'data':(94194175499568,False),'strides':None,'descr':[('','< i8')],'typestr':'< i8','shape':(3,4),版本":3}Y [0,1]是1个视图是否错误.Y [0,1] .__ array_interface__是{'data':(94194177613184,False),'strides':None,'descr':[('','< i8')],'typestr':'< i8','shape':(),'version':3,'__ref':array(1)} 

解决方案

 在[195]中:Y = np.arange(12).reshape(3,4)在[196]:Y出[196]:数组([[0,1,2,3],[4,5,6,7],[8、9、10、11]]) 

在2d数组上使用2个标量索引会从数组中返回一个元素,即 numpy 标量.

 在[197]中:Y [0,1]出[197]:1在[198]中:键入(_)出[198]:numpy.int64 

对于大多数用途,我们可以将此类对象视为Python整数.它确实具有 ndarray 之类的属性,例如 shape 甚至 __ array_interface __ ,但它不是 ndarray .

相比之下,数组本身的切片"就是数组:

 在[199]中:Y [0 ,:]Out [199]:数组([0,1,2,3])在[200]中:键入(_)出[200]:numpy.ndarray 

https://numpy.org/doc/stable/reference/arrays.scalars.html

此文档的一小部分显示了如何将数组标量视为0d数组.

 在[209]中:Y .__ array_interface __ ['data']Out [209] :( 38135024,False)在[210]中:Y [0,0] .__ array_interface __ ['data']Out [210] :( 35130688,False)在[211]中:Y [0,0,...] .__ array_interface __ ['data']Out [211] :( 38135024,False)在[212]中:Y [0,0]#数组标量出[212]:0在[213]中:Y [0,0,...]#0d数组出[213]:数组(0) 

要获取数组的元素,作为普通" Python类型:

 在[215]中:Y.item(0,0)出[215]:0在[216]中:键入(_)出[216]:整数 

Continuation to the question numpy - why Z[(0,2)] is view but Z[(0, 2), (0)] is copy?. I got the answer and understood that comma triggering advanced index makes a totally different indexing. The answer also provided a way using __array_interface__ to understand copy/view behavior.

However apparently I have not got to the bottom of this part of the answer.

A view is returned if the new array can be described with shape, strides and all or part of the original data buffer

Because I still cannot explain why the behavior below are different. Hence opening a new question to get to the bottom of this (shape, stride) mechanism to understand how view/copy works.

Kindly elaborate how numpy uses shhape and stride to determine to return a copy or not.

The first indexingX[0,1] returns a view.

X = np.arange(36).reshape(3, 3, 4)
print("X is \n{}\n".format(X))
print("X.__array_interface__ \n{}\n".format(X.__array_interface__))

_x =  X[
    0,
    2
]
print("X[0,1] is \n{}\nIs view? {}\n".format(
    _x,
    _x.base is not None
))
print("_x.__array_interface__ is \n{}\n".format(_x.__array_interface__))
---
X is 
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]

 [[24 25 26 27]
  [28 29 30 31]
  [32 33 34 35]]]

X.__array_interface__ 
{'data': (94194168544480, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (3, 3, 4), 'version': 3}

X[0,1] is 
[ 8  9 10 11]
Is view? True

_x.__array_interface__ is 
{'data': (94194168544544, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (4,), 'version': 3}

However, the next indexing with the same [0,1] returns a copy.

Y = np.arange(12).reshape(3, 4)
print("Y is \n{}\n".format(Y))
print("Y.__array_interface__ is \n{}\n".format(Y.__array_interface__))

_y = Y[
    0,
    1
]
print("Y[0,1] is \n{}\nIs view {}\n".format(
    _y,  
    _y.base is not None
))
print(".Y[0,1].__array_interface__ is \n{}\n".format(_y.__array_interface__))
---
Y is 
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

Y.__array_interface__ is 
{'data': (94194175499568, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (3, 4), 'version': 3}

Y[0,1] is 
1
Is view False

.Y[0,1].__array_interface__ is 
{'data': (94194177613184, False), 'strides': None, 'descr': [('', '<i8')], 'typestr': '<i8', 'shape': (), 'version': 3, '__ref': array(1)}

解决方案

In [195]: Y = np.arange(12).reshape(3,4)
In [196]: Y
Out[196]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Using 2 scalar indices on a 2d array returns one element from the array, a numpy scalar.

In [197]: Y[0,1]
Out[197]: 1
In [198]: type(_)
Out[198]: numpy.int64

For most purposes we can view such an object as Python integer. It does have ndarray like attributes such as shape and even __array_interface__, but it is not a ndarray.

In contrast a 'slice' of an array itself an array:

In [199]: Y[0,:]
Out[199]: array([0, 1, 2, 3])
In [200]: type(_)
Out[200]: numpy.ndarray

https://numpy.org/doc/stable/reference/arrays.scalars.html

This docs has a small section showing how an array scalar can be treated as a 0d array.

In [209]: Y.__array_interface__['data']
Out[209]: (38135024, False)
In [210]: Y[0,0].__array_interface__['data']
Out[210]: (35130688, False)
In [211]: Y[0,0,...].__array_interface__['data']
Out[211]: (38135024, False)
In [212]: Y[0,0]             # array scalar
Out[212]: 0
In [213]: Y[0,0,...]         # 0d array
Out[213]: array(0)

To get an element of the array, as a 'plain' Python type:

In [215]: Y.item(0,0)
Out[215]: 0
In [216]: type(_)
Out[216]: int

这篇关于numpy-为什么在某些情况下可以查看Z [(0,2)]而在其他情况下可以复制Z [(0,2)]?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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