Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change array layout?

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)
like image 515
Eka AW Avatar asked Sep 17 '26 06:09

Eka AW


1 Answers

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.

like image 112
Divakar Avatar answered Sep 18 '26 18:09

Divakar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!