Reputation: 77
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
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