Brad Solomon Brad Solomon - 3 years ago 243
Python Question

Passing new shape to `np.reshape`

Within

, the
shape
parameter is an int or tuple of ints, and


The new shape should be compatible with the original shape. If an
integer, then the result will be a 1-D array of that length.


The documentation signature is just:

# Note this question doesn't apply to the function version, `np.reshape`
np.ndarray.reshape(shape, order='C')


In practice the specification doesn't seem to be this strict. From the description above I would expect to need to use:

import numpy as np
a = np.arange(12)
b = a.reshape((4,3)) # (4,3) is passed to `newshape`


But instead I can get away with just:

c = a.reshape(4,3) # Seems like just 4 would be passed to `newshape`
# and 3 would be passed to next parameter, `order`
print(np.array_equal(b,c))
# True


How is it that I can do this? I know that if I just simply enter
2, 3
into a Python shell, it is technically a tuple whether I use parentheses or not. But the comparison above seems to violate basic laws of how positional parameters are passed to the dict of keyword args. I.e.:

def f(a, b=1, order='c'):
print(a)
print(b)

f((4,3))
print()
f(4,3)

# (4, 3)
# 1
#
# 4
# 3


...and there are no star operators in
reshape
. (Something akin to
def f(*a, order='c')
above.)

Answer Source

With the way that parameters are bound with normal Python methods, it should not work, but the method is not a Python method at all. Numpy is an extension module for CPython, and numpy.ndarray.reshape is actually implemented in C.

If you look at the implementation, the order parameter is only ever read as a keyword argument. A positional argument will never be bound to it, unlike with a normal Python method where the second positional argument would be bound to order. The C code tries to build the value for newshape from all of the positional arguments.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download