Why does this array-reshaping routine work outside

2019-09-18 16:33发布

I am trying to convert a list into a numpy array with a specified number of columns. I can get the code to work outside the function as follows:

import numpy as np

ls = np.linspace(1,100,100) # Data Sample
ls = np.array(ls) # list --> array

# resize | outside function
ls.resize(ls.shape[0]//2,2)
print(ls)

>> [[   1.    2.]
    [   3.    4.]
           .
           .
           .
    [  97.   98.]
    [  99.  100.]]

I do not understand my error when trying to throw the routine in a function. My attempt is as follows:

# resize | inside function
def shapeshift(mylist, num_col):
    num_col = int(num_col)
    return mylist.resize(mylist.shape[0]//num_col,num_col)

ls = shapeshift(ls,2)
print(ls)

>> None

I want to define the original function in this way because I want another function, consisting of the same inputs and a third input to loop over rows when extracting values, to call this original function for each loop over rows.

2条回答
爷的心禁止访问
2楼-- · 2019-09-18 16:56
In [402]: ls = np.linspace(1,100,10)
In [403]: ls
Out[403]: array([   1.,   12.,   23.,   34.,   45.,   56.,   67.,   78.,   89.,  100.])
In [404]: ls.shape
Out[404]: (10,)

No need to wrap again in array; it already is one:

In [405]: np.array(ls)
Out[405]: array([   1.,   12.,   23.,   34.,   45.,   56.,   67.,   78.,   89.,  100.])

resize operates in-place. It returns nothing (or None)

In [406]: ls.resize(ls.shape[0]//2,2)
In [407]: ls
Out[407]: 
array([[   1.,   12.],
       [  23.,   34.],
       [  45.,   56.],
       [  67.,   78.],
       [  89.,  100.]])
In [408]: ls.shape
Out[408]: (5, 2)

With this resize you aren't changing the number of elements, so reshape would work just as well.

In [409]: ls = np.linspace(1,100,10)
In [410]: ls.reshape(-1,2)
Out[410]: 
array([[   1.,   12.],
       [  23.,   34.],
       [  45.,   56.],
       [  67.,   78.],
       [  89.,  100.]])

reshape in either method or function form returns a value, leaving ls unchanged. The -1 is a handy short hand, avoiding the // division.

This is the inplace version of reshape:

In [415]: ls.shape=(-1,2)

reshape requires the same total number of elements. resize allows you to change the number of elements, truncating or repeating values if needed. We use reshape much more often then resize. repeat and tile are also more common than resize.

查看更多
乱世女痞
3楼-- · 2019-09-18 17:09

The .resize method works in-place and returns None. It also refuses to work at all if there are other names referencing the same array. You can use the function form, which creates a new array and is not as capricious:

def shapeshift(mylist, num_col):
    num_col = int(num_col)
    return np.resize(mylist, (mylist.size//num_col,num_col))
查看更多
登录 后发表回答