What is the efficient way to convert the following numpy arrays:
a1 = \
[[ 1.1 -1.1 0.1]
[ 2.1 -2.1 0.1]
[ 3.1 -3.1 0.1]
[ 4.1 -4.1 0.1]
[ 5.1 -5.1 0.1]]
and
a2 = \
[[ 1.2 -1.2 0.2]
[ 2.2 -2.2 0.2]
[ 3.2 -3.2 0.2]
[ 4.2 -4.2 0.2]
[ 5.2 -5.2 0.2]]
into A:
[[[ 1.1 1.2]
[ 2.1 2.2]
[ 3.1 3.2]
[ 4.1 4.2]
[ 5.1 5.2]]
[[-1.1 -1.2]
[-2.1 -2.2]
[-3.1 -3.2]
[-4.1 -4.2]
[-5.1 -5.2]]
[[ 0.1 0.2]
[ 0.1 0.2]
[ 0.1 0.2]
[ 0.1 0.2]
[ 0.1 0.2]]]
Is there a way to do it without copying data (e.g. modifying values in A would also modify corresponding values in a1 or in a2)?
UPD. Here's one of the accepted answers and the way back I have used - as copying is finally mandatory:
import numpy as np
a1 = [[ 1.1, -1.1, 0.1],
[ 2.1, -2.1, 0.1],
[ 3.1, -3.1, 0.1],
[ 4.1, -4.1, 0.1],
[ 5.1, -5.1, 0.1]]
a1 = np.array(a1)
a2 = [[ 1.2, -1.2, 0.2],
[ 2.2, -2.2, 0.2],
[ 3.2, -3.2, 0.2],
[ 4.2, -4.2, 0.2],
[ 5.2, -5.2, 0.2]]
a2 = np.array(a2)
a_expected = [[[ 1.1, 1.2],
[ 2.1, 2.2],
[ 3.1, 3.2],
[ 4.1, 4.2],
[ 5.1, 5.2]],
[[-1.1, -1.2],
[-2.1, -2.2],
[-3.1, -3.2],
[-4.1, -4.2],
[-5.1, -5.2]],
[[ 0.1, 0.2],
[ 0.1, 0.2],
[ 0.1, 0.2],
[ 0.1, 0.2],
[ 0.1, 0.2]]]
npar = 2
a = np.concatenate((a1[...,None].transpose(1,0,2), a2[...,None].transpose(1,0,2)), npar)
assert np.all(a == a_expected)
new_a1 = a.transpose(2, 1, 0)[0]
new_a2 = a.transpose(2, 1, 0)[1]
assert np.all(new_a1 == a1)
assert np.all(new_a2 == a2)
One approach with ndarray.transpose and np.concatenate -
np.concatenate((a1[...,None].transpose(1,0,2),a2[...,None].transpose(1,0,2)),2)
Another with ndarray.T and np.concatenate -
np.concatenate((a1.T[...,None],a2.T[...,None]),2)
Final compact one with ndarray.transpose and np.dstack -
np.dstack((a1,a2)).transpose(1,0,2)
Runtime tests -
In [63]: a1 = np.random.rand(500,300)
...: a2 = np.random.rand(500,300)
...:
In [64]: %timeit np.concatenate((a1[...,None].transpose(1,0,2),a2[...,None].transpose(1,0,2)),2)
100 loops, best of 3: 3.02 ms per loop
In [65]: %timeit np.concatenate((a1.T[...,None],a2.T[...,None]),2)
100 loops, best of 3: 3.03 ms per loop
In [66]: %timeit np.dstack((a1,a2)).transpose(1,0,2)
100 loops, best of 3: 3.05 ms per loop
In [67]: a1 = np.random.rand(5000,3000)
...: a2 = np.random.rand(5000,3000)
...:
In [68]: %timeit np.concatenate((a1[...,None].transpose(1,0,2),a2[...,None].transpose(1,0,2)),2)
1 loops, best of 3: 372 ms per loop
In [69]: %timeit np.concatenate((a1.T[...,None],a2.T[...,None]),2)
1 loops, best of 3: 373 ms per loop
In [70]: %timeit np.dstack((a1,a2)).transpose(1,0,2)
1 loops, best of 3: 371 ms per loop
It looks like, either one would be a good choice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With