Разбить n-мерный массив на 2D-массивы вдоль каждой оси - PullRequest
0 голосов
/ 22 октября 2018

Скажем, у меня есть массив произвольных измерений (сейчас мы дадим ему три измерения).

a=array([[[ 0,  1,  2,  3],
    [ 4,  5,  6,  7]],

   [[ 8,  9, 10, 11],
    [12, 13, 14, 15]],

   [[16, 17, 18, 19],
    [20, 21, 22, 23]]])

Какой самый простой способ разбить этот массив на список из двух измерениймассивы (в данном случае n-1, но 2) по всем различным осям, т.е.

new_array1=[[0, 1, 2, 3,], [4, 5, 6, 7]...[20, 21, 22, 23]]
new_array2=[[0, 4], [1, 5]...[19, 23]]
new_array3=[[0, 8, 16], [1, 9, 17]...[7, 15, 23]]

Есть ли простой способ сделать это для массива произвольной размерности?

Ответы [ 5 ]

0 голосов
/ 22 октября 2018

Первый:

a1 = [j for i in range(3) for j in a[i]]

Второй:

a2 = [list(zip(i[0], i[1])) for i in a]

Третий:

a3 = [list(zip(a[0][j], a[1][j], a[2][j])) for j in range(2)]
0 голосов
/ 22 октября 2018

Попробуйте:

b = list(map(lambda x:x.tolist(),np.split(a.flatten(),3)))

Или:

b = [i.tolist() for i in np.split(a.flatten(),3)]

Или:

b = list(map(lambda x:np.concatenate(x).tolist(),a))

Или:

b = [np.concatenate(i).tolist() for i in a]

Все случаи:

print(b)

Выходы:

[[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22, 23]]
0 голосов
/ 22 октября 2018

Вы можете использовать numpy's swapaxes() с reshape() для создания любой из этих фигур.

Например:

axis = 1
a.swapaxes(axis,2).reshape(-1,a.shape[axis])
> array([[ 0,  4],
   [ 1,  5],
   [ 2,  6],
   [ 3,  7],
   [ 8, 12],
   [ 9, 13],
   [10, 14],
   [11, 15],
   [16, 20],
   [17, 21],
   [18, 22],
   [19, 23]])

и

axis = 0
a.swapaxes(axis,2).reshape(-1, a.shape[axis])
>array([[ 0,  8, 16],
   [ 4, 12, 20],
   [ 1,  9, 17],
   [ 5, 13, 21],
   [ 2, 10, 18],
   [ 6, 14, 22],
   [ 3, 11, 19],
   [ 7, 15, 23]])

Первый пример можно сделать, просто изменив форму, так как он имеет одинаковые оси:

a.reshape(-1,4)
> array([[ 0,  1,  2,  3],
   [ 4,  5,  6,  7],
   [ 8,  9, 10, 11],
   [12, 13, 14, 15],
   [16, 17, 18, 19],
   [20, 21, 22, 23]])
0 голосов
/ 22 октября 2018

Вы можете использовать Moveaxis и изменить форму:

>>> from pprint import pprint
>>> import numpy as np
>>> 
>>> a = sum(np.ogrid[:2, :30:10, :400:100])
>>> a
array([[[  0, 100, 200, 300],
        [ 10, 110, 210, 310],
        [ 20, 120, 220, 320]],

       [[  1, 101, 201, 301],
        [ 11, 111, 211, 311],
        [ 21, 121, 221, 321]]])
>>> 
>>> pprint([np.moveaxis(a, j, -1).reshape(-1, d) for j, d  in enumerate(a.shape)])
[array([[  0,   1],
       [100, 101],
       [200, 201],
       [300, 301],
       [ 10,  11],
       [110, 111],
       [210, 211],
       [310, 311],
       [ 20,  21],
       [120, 121],
       [220, 221],
       [320, 321]]),
 array([[  0,  10,  20],
       [100, 110, 120],
       [200, 210, 220],
       [300, 310, 320],
       [  1,  11,  21],
       [101, 111, 121],
       [201, 211, 221],
       [301, 311, 321]]),
 array([[  0, 100, 200, 300],
       [ 10, 110, 210, 310],
       [ 20, 120, 220, 320],
       [  1, 101, 201, 301],
       [ 11, 111, 211, 311],
       [ 21, 121, 221, 321]])]

Разница между Moveaxis и Swapaxes здесь заключается в том, что Moveaxis сохраняет порядок оставшихся измерений.

0 голосов
/ 22 октября 2018

Попробуйте:

b = []                                                 
for i in a:
    b.append([item for sublist in i for item in sublist])

Вывод:

[[0, 1, 2, 3, 4, 5, 6, 7],
 [8, 9, 10, 11, 12, 13, 14, 15],
 [16, 17, 18, 19, 20, 21, 22, 23]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...