Изменение формы и индексация в MATLAB и Python - PullRequest
0 голосов
/ 17 января 2020

У меня есть код в Matlab, который мне нужно перевести в Python. Дело в том, что формы и индексы действительно важны, поскольку они работают с тензорами. Я немного запутался, поскольку кажется, что достаточно использовать order='F' в python reshape(). Но когда я работаю с 3D-данными, я заметил, что это не работает. Например, если A - это массив от 1 до 27 в python

array([[[ 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]]])

, если я выполняю A.reshape(3, 9, order='F'), я получаю

[[ 1  4  7  2  5  8  3  6  9]
 [10 13 16 11 14 17 12 15 18]
 [19 22 25 20 23 26 21 24 27]]

в Matlab для A = 1:27 изменив форму на [3, 3, 3], а затем на [3, 9], кажется, что я получаю другой массив:

1     4     7    10    13    16    19    22    25
2     5     8    11    14    17    20    23    26
3     6     9    12    15    18    21    24    27

И SVD в Matlab и Python дает разные результаты. Итак, есть ли способ это исправить?

И, возможно, вы знаете правильный способ работы с многомерными массивами в Matlab -> python, как если бы я получил такой же SVD для массивов, как arange (1, 13) .reshape (3, 4) и в Matlab 1:12 -> изменить форму (_, [3, 4]) или как правильно с этим работать? Может быть, я могу поменять оси как-то в python, чтобы получить те же результаты, что и в Matlab? Или изменить порядок осей в reshape(x1, x2, x3,...) в Python?

Ответы [ 2 ]

0 голосов
/ 18 января 2020

У меня были те же проблемы, пока я не нашел эту статью в Википедии: порядок строк и столбцов

Python (и C) организует массивы данных в ряд крупных заказов. Как вы можете видеть в первом примере кода, элементы сначала увеличиваются вместе со столбцами:

array([[[ 1,  2,  3],
          - - - -> increasing

Затем в строках

array([[[ 1,  2,  3],
      [ 4,   <--- new element

Когда все столбцы и строки заполнены, он перемещается на следующую страницу.

array([[[ 1,  2,  3],
    [ 4,  5,  6],
    [ 7,  8,  9]],

   [[10,  <-- new element in next page

В matlab (как fortran) увеличивается сначала строки, затем столбцы и т. д.

Для массивов N-мерного типа это выглядит так:

  • Python (главная строка -> последнее измерение непрерывно): [dim1, dim2, ..., dimN]
  • Matlab (главная колонка -> первое измерение непрерывно): тот же тензор в памяти выглядел бы наоборот ... [dimN, ..., dim2, dim1]

Если вы хотите экспортировать n-dim. Для массивов от python до matlab проще всего сначала переставить размеры: (в python)

import numpy as np
import scipy.io as sio
A=np.reshape(range(1,28),[3,3,3])
sio.savemat('A',{'A':A})

(в matlab)

load('A.mat')
A=permute(A,[3 2 1]);%dimensions in reverse ordering
reshape(A,9,3)' %gives the same result as A.reshape([3,9]) in python

Просто обратите внимание, что (9,3) и (3,9) намеренно ставятся в обратном порядке.

0 голосов
/ 17 января 2020

В Matlab

A = 1:27;
A = reshape(A,3,3,3);
B = reshape(A,9,3)'
B =

     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
size(B)

ans =

     3     9

В Python

A = np.array(range(1,28))
A = A.reshape(3,3,3)
B = A.reshape(3,9)
B
array([[ 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]])
np.shape(B)
 (3, 9)
...