我想了解裸体的行为。在
当我试图获取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
。在
^{pr2}$
我的问题是,那是纽比的故意行为吗?如果是这样,如果我想创建NumPy数组内部对象的引用,我应该怎么做。在
Tags:
现在不确定它是否有用,但
numpy.ndarray.ctypes
似乎有有用的位: https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.ctypes.html用了这样的东西(缺少
dtype
,但是meh):这里: https://github.com/EricCousineau-TRI/repro/blob/a60daf899e9726daf2ca1259bb80ad2c7c9b3e3f/python/namedlist_alt.py#L111
二维切片
当我第一次写这篇文章时,我构建了一个一维数组并编制了索引。但是OP使用的是2d数组,所以
x[0]
是一个“行”,是原始数组的一部分。在我之前写的关于切片的文章仍然适用。为单个元素建立索引,如
arr[0,0]
的工作原理与1d数组相同。在这个2d arr与1d}之间的区别仍然适用。在
arr.ravel()
具有相同的数据缓冲区;形状和跨距是不同的。而且view
、copy
和{在C中实现2d数组的一种常见方法是使用指向其他数组的指针数组。}参数来实现交叉。因此子数组需要它自己的}以及指向共享数据缓冲区的指针。在
numpy
采用不同的strided
方法,只使用一个平面数据数组,并使用shape
和{shape
和{一维阵列索引
我将尝试演示索引数组时发生的情况:
^{pr2}$数组是一个具有各种属性的对象,例如形状和数据缓冲区。缓冲区将数据存储为字节(在C数组中),而不是Python数字对象。您可以通过以下方式查看有关阵列的信息:
或者
一个是十六进制的数据指针,另一个是十进制的。我们通常不会直接引用它。在
如果我索引一个元素,我会得到一个新对象:
它有数组的一些属性,但不是全部。例如,您不能分配给它。还要注意,它的“data”值是完全不同的。在
从同一个地方进行另一个选择-不同的id和不同的数据:
另外,如果此时更改阵列,则不会影响之前的选择:
x1
和x2
没有相同的id
,因此与is
不匹配,它们也不使用arr
数据缓冲区。没有记录表明这两个变量都是从arr
派生的。在使用
slicing
可以得到原始数组的view
它的数据指针比
arr
大4个字节,也就是说,它指向同一个缓冲区,只是一个不同的点。而改变y
确实改变了arr
(但不是独立的x1
)。在我甚至可以查看此项目的0d视图
在Python代码中,我们通常不处理这样的对象。当我们使用}时,是否可以直接访问数据缓冲区。
c-api
或{nditer
是一种迭代机制,可以处理像这样的0d对象(在Python或c-api中)。Incython
typed memoryviews
对于低级访问特别有用。在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
元素方面==
作为对评论的回应,Comparing NumPy object references
==
是为数组定义的元素操作。它比较各个元素的值并返回匹配的布尔数组。在如果这种比较需要在标量上下文中使用(例如}。在
if
),则需要将其缩减为单个值,如np.all
或{is
测试比较对象id(不仅仅是numpy对象)。它在实际编码中的应用价值有限。我经常在is None
之类的表达式中使用它,其中None
是一个具有唯一id的对象,它不能很好地用于等式测试。在我想你对Numpy数组的理解有点欠缺。您认为Numpy中多维数组中的子数组(就像Python列表中的子数组)是独立的对象,其实它们不是。在
一个Numpy数组,不管它的维数是多少,都只是一个对象。这是因为Numpy在C级别创建数组,当将它们作为python对象加载时,不能将其分解为多个对象。这使得Python在使用诸如
split()
、__getitem__
、take()
等属性时,创建一个新对象来保存新的部分,事实上,这正是Python为Numpy数组抽象类似于列表的行为的方式。在您还可以实时检查精简,如下所示:
所以一旦你有了一个数组或者任何一个可以容纳其他对象的可变对象,你就会有一个python可变对象,因此你将失去Numpy数组的性能和所有其他优秀特性。在
另外,正如@Imanol在评论中提到的,如果您想在使用引用修改数组时有一个内存优化和灵活的操作,那么您可能需要使用Numpy视图对象。
view
可以通过以下两种方式构造对象:相关问题 更多 >
编程相关推荐