Skip to content Skip to sidebar Skip to footer

What Does It Mean "the Reshape Function Returns Its Argument With A Modified Shape, Whereas The Ndarray.resize Method Modifies The Array Itself"?

In Numpy, the reshape function returns its argument with a modified shape, whereas the ndarray.resize method modifies the array itself. But what does this really mean? What's the r

Solution 1:

In [15]: a = np.arange(18) 
    ...: b = a.reshape(3,6)  

I like to examine the properties of arrays with:

In [16]: a.__array_interface__                                                                               
Out[16]: 
{'data': (65611776, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (18,),
 'version': 3}
In [17]: b.__array_interface__                                                                               
Out[17]: 
{'data': (65611776, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (3, 6),
 'version': 3}

Note that data is the same for both. b is a view of a. It is a new array object, but it shares the underlying data buffer. Its shape is different, but changes to a will appear as changes in b (and visa versa).

Review documentation regarding view versus copy. This is an important distinction in numpy, so you need to understand it well.

Sometimes reshape has to return a copy, as when order gets changed. It's also important to realize the reshape cannot change the number of elements.

There's a reshape function as well, which in most cases the same as the method.

The shape attribute can be changed directly as well:

In [19]: a.shape = (6,3)                                                                                     
In [20]: a                                                                                                   
Out[20]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17]])
In [21]: b                                                                                                   
Out[21]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])

That action is in-place, modifying a itself. It's a little more restrictive than reshape, and not used as often. For example we could have made b with one line:

b = np.arange(18).reshape(3,6)

The key difference in resize is that it can change the number of elements. It can truncate, or it can increase the size. The resize method and function both do this, but have different 'padding' rules. And the resize method operates in-place.

In your example, a.resize(3,6) changed a in-place, changing its shape, but did not change its data buffer, or b's link to that buffer. So changes to a also appeared as changes in b.

My a after the in-place shape change still has the same data:

In [22]: a.__array_interface__                                                                               
Out[22]: 
{'data': (65611776, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (6, 3),
 'version': 3}

and the same data after a resize method.

In [23]: a.resize(3,6)                                                                                       
In [24]: a.__array_interface__                                                                               
Out[24]: 
{'data': (65611776, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (3, 6),
 'version': 3}

Note that if I try to resizea in a way that changes the total number of elements, I get an error. That's because b shares the data buffer, and we can't change the size of a without affecting the size of b.

In [28]: a.resize(4,6)                                                                                       
---------------------------------------------------------------------------
ValueError                                Traceback (most recent calllast)
<ipython-input-28-f7d47a627631>in<module>----> 1 a.resize(4,6)

ValueError: cannot resize an array that referencesoris referenced
by another arrayin this way.
Use the np.resize functionor refcheck=False

I think you'll find np.reshape and a.reshape are used quite a bit. resize in either form is not used nearly as often. reshape is more predictable and safer. resize can do the same, but it also lets you do dangerous stuff.

I'd focus on understanding the difference between a view and copy, and secondarily the difference between making a new array and doing in-place changes.

Solution 2:

It means that one function will modify the array, and you only will have the modified array.

The other will return a new array, modified, but leave the original one untouched. It will use double the memory, but the original array will remain available for other calculations.

Depending on the circumstances you might prefer the one or the other.

Solution 3:

I think this is best explained through examples.

import numpy as np

a = np.arange(18)

b = a

print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]print(b)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]print("Reshape - doesnt change the base array")
print(a.reshape(3,6))
#[[ 0  1  2  3  4  5]# [ 6  7  8  9 10 11]# [12 13 14 15 16 17]]print(b)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]

b = a.reshape(3,6)
print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]print(b)
#[[ 0  1  2  3  4  5]# [ 6  7  8  9 10 11]# [12 13 14 15 16 17]]

a = np.arange(18)
b = a

print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]print(b)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17]print("resize changes the actual base array")
a.resize(3,6)
print(a)
#[[ 0  1  2  3  4  5]# [ 6  7  8  9 10 11]# [12 13 14 15 16 17]]print(b)
#[[ 0  1  2  3  4  5]# [ 6  7  8  9 10 11]# [12 13 14 15 16 17]]

Post a Comment for "What Does It Mean "the Reshape Function Returns Its Argument With A Modified Shape, Whereas The Ndarray.resize Method Modifies The Array Itself"?"