Изменение формы данных в Python (список / массив) - PullRequest
1 голос
/ 12 мая 2019

У меня есть следующий массив Numpy.enter image description here

Я хочу изменить его на (3,5,3)

Так что я должен быть как:

[
[
[1,6,11],
[2,7,12],
[3,8,13],
[4,9,14],
[5,10,15]
],.......
]

Я попытался изменить (3,5,3), но это не дает желаемого результата?

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Ваш входной массив имеет форму (3, 3, 5), и вы хотите, чтобы он был преобразован в (3, 5, 3). Есть много способов сделать это. Ниже приведены некоторые из них, которые также упоминаются в комментариях:

Сначала будет использоваться numpy.reshape(), который принимает newshape в качестве параметра:

In [77]: arr = np.arange(3*3*5).reshape(3, 3, 5)

# reshape to desired shape
In [78]: arr = arr.reshape((3, 5, 3))

In [79]: arr.shape
Out[79]: (3, 5, 3)

Или вы можете использовать numpy.transpose() как в:

In [80]: arr = np.arange(3*3*5).reshape(3, 3, 5)

In [81]: arr.shape
Out[81]: (3, 3, 5)

# now, we want to move the last axis which is 2 to second position
# thus our new shape would be `(3, 5, 3)`
In [82]: arr = np.transpose(arr, (0, 2, 1))

In [83]: arr.shape
Out[83]: (3, 5, 3)

Другим способом будет использование numpy.moveaxis():

In [87]: arr = np.arange(3*3*5).reshape(3, 3, 5)

# move the last axis (-1) to 2nd position (1)
In [88]: arr = np.moveaxis(arr, -1, 1)

In [89]: arr.shape
Out[89]: (3, 5, 3)

Еще одним способом было бы просто поменять оси, используя numpy.swapaxes():

In [90]: arr = np.arange(3*3*5).reshape(3, 3, 5)

In [91]: arr.shape
Out[91]: (3, 3, 5)

# swap the position of ultimate and penultimate axes
In [92]: arr = np.swapaxes(arr, -1, 1)

In [93]: arr.shape
Out[93]: (3, 5, 3)

Выберите тот, который вам интуитивнее, поскольку все подходы возвращают новый вид желаемой формы.


Хотя все вышеперечисленное возвращает представление, существуют некоторые временные различия. Таким образом, предпочтительный способ сделать это (для эффективности) будет:

In [124]: arr = np.arange(3*3*5).reshape(3, 3, 5)

In [125]: %timeit np.swapaxes(arr, -1, 1)
456 ns ± 6.79 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [126]: %timeit np.transpose(arr, (0, 2, 1))
458 ns ± 6.93 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [127]: %timeit np.reshape(arr, (3, 5, 3))
635 ns ± 9.06 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [128]: %timeit np.moveaxis(arr, -1, 1)
3.42 µs ± 79.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

numpy.swapaxes() и numpy.transpose() занимают почти одно и то же время: numpy.reshape() немного медленнее, а numpy.moveaxis медленнее всех. Поэтому было бы разумно использовать swapaxes или transpose ufunc.

0 голосов
/ 12 мая 2019

Я нашел способ сделать это, используя List comprehension и Numpy transpose.

Код:

import numpy as np
database = [
        [
            [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]
        ]
    ]

ans = [np.transpose(data) for data in database]
print(ans)

Выход:

[array([[ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14],
       [ 5, 10, 15]]), 
 array([[16, 21, 26],
       [17, 22, 27],
       [18, 23, 28],
       [19, 24, 29],
       [20, 25, 30]]), 
 array([[31, 36, 41],
       [32, 37, 42],
       [33, 38, 43],
       [34, 39, 44],
       [35, 40, 45]])]
...