python – 比较NumPy对象引用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 比较NumPy对象引用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4095字,纯文字阅读大概需要6分钟。
内容图文
![python – 比较NumPy对象引用](/upload/InfoBanner/zyjiaocheng/789/d95e06cd29034807a037cc8f9d4f1265.jpg)
我想了解NumPy的行为.
当我尝试获取NumPy数组的内部数组的引用,然后将其与对象本身进行比较时,我得到返回值False.
这是一个例子:
In [198]: x = np.array([[1,2,3], [4,5,6]])
In [201]: x0 = x[0]
In [202]: x0 is x[0]
Out[202]: False
另一方面,对于Python本机对象,返回的是True.
In [205]: c = [[1,2,3],[1]]
In [206]: c0 = c[0]
In [207]: c0 is c[0]
Out[207]: True
我的问题是,NumPy的预期行为是什么?如果是这样,如果我想创建NumPy数组的内部对象的引用,我该怎么办.
解决方法:
2d切片
当我第一次写这篇文章时,我构建并索引了一个1d数组.但是OP正在使用2d数组,所以x [0]是’row’,是原始的一部分.
In [81]: arr = np.array([[1,2,3], [4,5,6]])
In [82]: arr.__array_interface__['data']
Out[82]: (181595128, False)
In [83]: x0 = arr[0,:]
In [84]: x0.__array_interface__['data']
Out[84]: (181595128, False) # same databuffer pointer
In [85]: id(x0)
Out[85]: 2886887088
In [86]: x1 = arr[0,:] # another slice, different id
In [87]: x1.__array_interface__['data']
Out[87]: (181595128, False)
In [88]: id(x1)
Out[88]: 2886888888
我之前写的关于切片的内容仍然适用.索引单个元素,与arr [0,0]一样,与1d数组的工作方式相同.
这个2d arr与1d arr.ravel()具有相同的数据缓冲区;形状和步幅不同.而视图,副本和项目之间的区别仍然适用.
在C中实现2d数组的常用方法是使用指向其他数组的指针数组. numpy采用不同的,跨步的方法,只有一个平面数据阵列,并使用形状和步长参数来实现横向.因此,子阵列需要自己的形状和步幅以及指向共享数据缓冲区的指针.
1d数组索引
我将尝试说明索引数组时发生的事情:
In [51]: arr = np.arange(4)
该数组是具有各种属性(如形状)和数据缓冲区的对象.缓冲区将数据存储为字节(在C数组中),而不是Python数字对象.您可以在以下位置查看有关阵列的信息:
In [52]: np.info(arr)
class: ndarray
shape: (4,)
strides: (4,)
itemsize: 4
aligned: True
contiguous: True
fortran: True
data pointer: 0xa84f8d8
byteorder: little
byteswap: False
type: int32
要么
In [53]: arr.__array_interface__
Out[53]:
{'data': (176486616, False),
'descr': [('', '<i4')],
'shape': (4,),
'strides': None,
'typestr': '<i4',
'version': 3}
一个数据指针为十六进制,另一个为十进制.我们通常不直接引用它.
如果我索引一个元素,我得到一个新对象:
In [54]: x1 = arr[1]
In [55]: type(x1)
Out[55]: numpy.int32
In [56]: x1.__array_interface__
Out[56]:
{'__ref': array(1),
'data': (181158400, False),
....}
In [57]: id(x1)
Out[57]: 2946170352
它具有数组的一些属性,但不是全部.例如,您无法分配给它.另请注意,其“数据”值完全不同.
从同一个地方做另一个选择 – 不同的id和不同的数据:
In [58]: x2 = arr[1]
In [59]: id(x2)
Out[59]: 2946170336
In [60]: x2.__array_interface__['data']
Out[60]: (181143288, False)
此外,如果我此时更改数组,它不会影响先前的选择:
In [61]: arr[1] = 10
In [62]: arr
Out[62]: array([ 0, 10, 2, 3])
In [63]: x1
Out[63]: 1
x1和x2没有相同的id,因此与is不匹配,并且它们也不使用arr数据缓冲区.没有任何记录表明这两个变量都来自arr.
通过切片,可以获得原始数组的视图,
In [64]: y = arr[1:2]
In [65]: y.__array_interface__
Out[65]:
{'data': (176486620, False),
'descr': [('', '<i4')],
'shape': (1,),
....}
In [66]: y
Out[66]: array([10])
In [67]: y[0]=4
In [68]: arr
Out[68]: array([0, 4, 2, 3])
In [69]: x1
Out[69]: 1
它的数据指针比arr大4个字节 – 也就是说,它指向同一个缓冲区,只是一个不同的位置.改变y确实改变了arr(但不是独立的x1).
我甚至可以对这个项目进行0d视图
In [71]: z = y.reshape(())
In [72]: z
Out[72]: array(4)
In [73]: z[...]=0
In [74]: arr
Out[74]: array([0, 0, 2, 3])
在Python代码中,我们通常不使用这样的对象.当我们使用c-api或cython时,可以直接访问数据缓冲区. nditer是一种迭代机制,可以像这样使用0d对象(在Python或c-api中).在cython类型中,内存视图对于低级访问特别有用.
http://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html
https://docs.scipy.org/doc/numpy/reference/arrays.nditer.html
https://docs.scipy.org/doc/numpy/reference/c-api.iterator.html#c.NpyIter
elementwise ==
回应评论,Comparing NumPy object references
np.array([1]) == np.array([2]) will return array([False], dtype=bool)
==被定义为数组作为元素操作.它比较各个元素的值并返回匹配的布尔数组.
如果需要在标量上下文(例如if)中使用这种比较,则需要将其缩减为单个值,如np.all或np.any.
is测试比较对象id(不仅仅是numpy对象).它在实际编码中的价值有限.我经常在像None这样的表达式中使用它,其中None是具有唯一id的对象,并且不能很好地使用相等测试.
内容总结
以上是互联网集市为您收集整理的python – 比较NumPy对象引用全部内容,希望文章能够帮你解决python – 比较NumPy对象引用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。