Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

python - Numpy, the array doesn't have its own data?

I tried to use resize on an array in this way:

a = np.array([1,2,3,4,5,6], dtype=np.uint8)
a.resize(4,2)
print a 

and the output is Ok!(I meant that there was no error). But when I run this code:

a = np.array([1,2,3,4,5,6], dtype=np.uint8).reshape(2,3)
a.resize(4,2)
print a 

it gave rise to an error, saying that, ValueError: cannot resize this array: it does not own its data

My question: why after applying reshape the ownership of array is changed? The ownership is granted to whom !? The reshape does not create a new memory and it is performing its operation on the same array memory! So why the ownership will change?

I read np.reshape and ndarray.resize doc but I can not understand the reason. I read this post. I can check ndarray.flags always before applying the resize method.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Lets start with the following:

>>> 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)

I can see here that array b is not its own array, but simply a view of a (just another way to understand the "OWNDATA" flag). To put it simply both a and b reference the same data in memory, but b is viewing a with a different shape. Calling the resize function like ndarray.resize tries to change the array in place, as b is just a view of a this is not permissible as from the resize definition:

The purpose of the reference count check is to make sure you do not use this array as a buffer for another Python object and then reallocate the memory.


To circumvent your issue you can call resize from numpy (not as an attribute of a ndarray) which will detect this issue and copy the data automatically:

>>> np.resize(b,(4,2))
array([[5, 2],
       [3, 4],
       [5, 6],
       [5, 2]], dtype=uint8)

Edit: As CT Zhu correctly mention np.resize and ndarray.resize add data in two different ways. To reproduce expected behavior as ndarray.resize you would have to do the following:

>>> c = b.copy()
>>> c.resize(4,2)
>>> c
array([[5, 2],
       [3, 4],
       [5, 6],
       [0, 0]], dtype=uint8)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...