SO1999
SO1999

Reputation: 77

Elegant and Efficient Numpy Array Operations - np.linspace

I would like to more beautifully create arr3 from arr. I will mark the solution which is most elegant and efficient for a large number of rows (~10^7) as the accepted answer.

>>> arr = np.array([3,30])
>>> arr
array([  3,  30])
>>> arr2 = np.array([np.linspace(arr[i]/3, arr[i], 3).reshape(-1,1)
                     for i in range(len(arr))])
>>> list(arr2)
[array([[1.],
        [2.],
        [3.]]),
 array([[10.],
        [20.],
        [30.]])]
>>> arr3 = np.tile(arr2,4)
>>> list(arr3)
[array([[1., 1., 1., 1.],
        [2., 2., 2., 2.],
        [3., 3., 3., 3.]]),
 array([[10., 10., 10., 10.],
        [20., 20., 20., 20.],
        [30., 30., 30., 30.]])]

I believe creating a higher dimensional array from np.linspace can get immediately to arr2 and maybe even arr3 but I am not sure how, though you don't have to use np.linspace if this is not the best way.

Second question: If the inner two arrays of arr3 were instead required to be transposed, how would this be achieved directly from arr? It is simple from arr3 but perhaps there is a more direct way analogous to the original problem.

Thank you!

Upvotes: 2

Views: 217

Answers (1)

hpaulj
hpaulj

Reputation: 231540

In [38]: arr
Out[38]: array([ 3, 30])

linspace allows us to specify arrays as the end points:

In [39]: np.linspace(arr/3, arr, 3)
Out[39]: 
array([[ 1., 10.],
       [ 2., 20.],
       [ 3., 30.]])

transpose and reshape produces your arr2:

In [40]: np.linspace(arr/3, arr, 3).T
Out[40]: 
array([[ 1.,  2.,  3.],
       [10., 20., 30.]])

In [41]: np.linspace(arr/3, arr, 3).T.reshape(2,-1,1)
Out[41]: 
array([[[ 1.],
        [ 2.],
        [ 3.]],

       [[10.],
        [20.],
        [30.]]])

Then just use repeat (or tile) to expand it:

In [42]: np.linspace(arr/3, arr, 3).T.reshape(2,-1,1).repeat(4,-1)
Out[42]: 
array([[[ 1.,  1.,  1.,  1.],
        [ 2.,  2.,  2.,  2.],
        [ 3.,  3.,  3.,  3.]],

       [[10., 10., 10., 10.],
        [20., 20., 20., 20.],
        [30., 30., 30., 30.]]])

Another order for applying these operations:

np.linspace(arr/3,arr,3).repeat(4,1).reshape(3,2,4).transpose(1,0,2)

Upvotes: 2

Related Questions