我尝试以这种方式在数组上使用resize
:
a = np.array([1,2,3,4,5,6], dtype=np.uint8)
a.resize(4,2)
print a
输出正常!(我的意思是没有错误)。但是当我运行这段代码时:
a = np.array([1,2,3,4,5,6], dtype=np.uint8).reshape(2,3)
a.resize(4,2)
print a
它引起了一个错误,说ValueError: cannot resize this array: it does not own its data
我的问题:为什么在应用reshape
后,数组的所有权发生了变化?所有权授予谁!? reshape
不会创建新内存,而是在同一阵列内存上执行操作!那么为什么所有权会改变呢?
我看过np.reshape和ndarray.resize doc,但我无法理解原因。我看了this post。在应用ndarray.flags
方法之前,我始终可以检查resize
。
答案 0 :(得分:13)
让我们从以下内容开始:
>>> a = np.array([1,2,3,4,5,6], dtype=np.uint8)
>>> b = a.reshape(2,3)
>>> b[0,0] = 5
>>> a
array([5, 2, 3, 4, 5, 6], dtype=uint8)
我在这里可以看到数组b
不是它自己的数组,只是a
的视图(只是了解" OWNDATA"标志的另一种方式)。简而言之,a
和b
都会在内存中引用相同的数据,但b
正在查看具有不同形状的a
。调用像resize
这样的ndarray.resize
函数尝试更改数组到位,因为b
只是a
的视图,这是不允许的来自resize
定义:
引用计数检查的目的是确保不将此数组用作另一个Python对象的缓冲区,然后重新分配内存。
要绕过您的问题,您可以从numpy(不是ndarray的属性)调用resize
来检测此问题并自动复制数据:
>>> np.resize(b,(4,2))
array([[5, 2],
[3, 4],
[5, 6],
[5, 2]], dtype=uint8)
编辑:正如CT朱正确提到np.resize
和ndarray.resize
以两种不同的方式添加数据。要将预期行为重现为ndarray.resize
,您必须执行以下操作:
>>> c = b.copy()
>>> c.resize(4,2)
>>> c
array([[5, 2],
[3, 4],
[5, 6],
[0, 0]], dtype=uint8)