vasco_t
vasco_t

Reputation: 133

Numpy arrays - Convert a 3D array to a 2D array

Having the following 3D array (9,9,9):

np.arange(729).reshape((9,9,9))

[[[  0   1   2   3   4   5   6   7   8]
  [  9  10  11  12  13  14  15  16  17]
  [ 18  19  20  21  22  23  24  25  26]
  [ 27  28  29  30  31  32  33  34  35]
  [ 36  37  38  39  40  41  42  43  44]
  [ 45  46  47  48  49  50  51  52  53]
  [ 54  55  56  57  58  59  60  61  62]
  [ 63  64  65  66  67  68  69  70  71]
  [ 72  73  74  75  76  77  78  79  80]]
...
  [[648 649 650 651 652 653 654 655 656]
  [657 658 659 660 661 662 663 664 665]
  [666 667 668 669 670 671 672 673 674]
  [675 676 677 678 679 680 681 682 683]
  [684 685 686 687 688 689 690 691 692]
  [693 694 695 696 697 698 699 700 701]
  [702 703 704 705 706 707 708 709 710]
  [711 712 713 714 715 716 717 718 719]
  [720 721 722 723 724 725 726 727 728]]]

How do I reshape it to look like this 2D array (27,27):

[[0 1 2 3 4 5 6 7 8 81 82 83 84 85 86 87 88 89 162 163 164 165 166 167 168 169 170]     
 [9 10 11 12 13 14 15 16 17 90 91 92 93 94 95 96 97 98 171 172 173 174 175 176 177 178 179]
 ...
 [558 559 560 561 562 563 564 565 566 639 640 641 642 643 644 645 646 647 720 721 722 723 724 725 726 727 728]

Upvotes: 2

Views: 510

Answers (3)

Kruupös
Kruupös

Reputation: 5484

import numpy as np

x = np.arange(729).reshape(9, 9, 9)

y = x.transpose(1, 0, 2).reshape(27, 27)
y[y[:,2].argsort()]

Explanations

I used numpy.transpose to permute the stride and shape information for each axis.

>>> x.strides
(324L, 36L, 4L)
>>> x.transpose(1, 0, 2).strides
(36L, 324L, 4L)

more info in this answer.

Then I used numpy.reshape the 3D (9L, 9L, 9L) in 2D as expected

>>> x.reshape(27, 27)
(27L, 27L)

Of course, the combination of functions (like transpose and reshape) is very common in numpy. It allows you do to this matrix transformation in a one-liner:

x.transpose(1, 0, 2).reshape(27, 27)

EDIT

As @PaulPanzer point it out, the array was unsorted.

To sort array column by column, one can use:

y[y[:,2].argsort()]

But maybe it isn't the easiest answer anymore.

Upvotes: 1

James
James

Reputation: 36746

If you are ok with moving data in a list you can use:

np.hstack([x for x in np.arange(729).reshape((9,9,9))])

Upvotes: 0

akuiper
akuiper

Reputation: 215117

You can firstly reshape the array to a 4d array, swap the second and third axises and then reshape it to 27 X 27:

a.reshape(3,3,9,9).transpose((0,2,1,3)).reshape(27,27)

#array([[  0,   1,   2,   3,   4,   5,   6,   7,   8,  81,  82,  83,  84,
#         85,  86,  87,  88,  89, 162, 163, 164, 165, 166, 167, 168, 169,
#        170],
#       [  9,  10,  11,  12,  13,  14,  15,  16,  17,  90,  91,  92,  93,
#         94,  95,  96,  97,  98, 171, 172, 173, 174, 175, 176, 177, 178,
#        179],
#  ... 
#       [558, 559, 560, 561, 562, 563, 564, 565, 566, 639, 640, 641, 642,
#        643, 644, 645, 646, 647, 720, 721, 722, 723, 724, 725, 726, 727,
#        728]])

Upvotes: 2

Related Questions