MATLAB Numpy поэлементное умножение - PullRequest
0 голосов
/ 18 января 2019

Пожалуйста, смотрите код MATLAB и эквивалентный код Numpy ниже. Вопрос: Как я могу получить переменную D в Numpy так же, как в MATLAB?

Код MATLAB

A = [1 2 3; 4 5 6; 7 8 9]

C = [100 1; 10 0.1; 1, 0.01]

C = reshape(C, 1,3,2)

D = bsxfun(@times, A, C)

D(:,:,1) =

       100    20     3
       400    50     6
       700    80     9

D(:,:,2) =

    1.0000    0.2000    0.0300
    4.0000    0.5000    0.0600
    7.0000    0.8000    0.0900

Код Numpy

A = np.array([[1,2,3],[4,5,6],[7,8,9]])

C = np.array([[[100, 1], [10, 0.1], [1, 0.01]]]) # C.shape is (1, 3, 2)

D = A * C.T

D

    array([[[100.  , 200.  , 300.  ],
            [ 40.  ,  50.  ,  60.  ],
            [  7.  ,   8.  ,   9.  ]],

           [[  1.  ,   2.  ,   3.  ],
            [  0.4 ,   0.5 ,   0.6 ],
            [  0.07,   0.08,   0.09]]])

Ответы [ 2 ]

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

Вы были близки. Вы можете сделать это, умножив транспонирование матриц, а затем транспонировав окончательные субматрицы, используя свопаксы

A = np.array([[1,2,3],[4,5,6],[7,8,9]])
C = np.array([[[100, 1], [10, 0.1], [1, 0.01]]]) # C.shape is (1, 3, 2)

D = (A.T*C.T)
D = D.swapaxes(1,2)

Вы также можете объединить эти строки как

D = (A.T*C.T).swapaxes(1,2)

выход

array([[[1.e+02, 2.e+01, 3.e+00],
    [4.e+02, 5.e+01, 6.e+00],
    [7.e+02, 8.e+01, 9.e+00]],

   [[1.e+00, 2.e-01, 3.e-02],
    [4.e+00, 5.e-01, 6.e-02],
    [7.e+00, 8.e-01, 9.e-02]]])
0 голосов
/ 18 января 2019

Вы добавили транспонирование в C, которого нет в коде MATLAB.

Если вы хотите сохранить точно такой же формат данных, введите конечный одноэлементный размер в A. В MATLAB конечные неявные синглтоны, в numpy ведущие неявные синглтоны:

>>> D = A[...,None] * C.squeeze()

>>> D
array([[[1.e+02, 1.e+00],
        [2.e+01, 2.e-01],
        [3.e+00, 3.e-02]],

       [[4.e+02, 4.e+00],
        [5.e+01, 5.e-01],
        [6.e+00, 6.e-02]],

       [[7.e+02, 7.e+00],
        [8.e+01, 8.e-01],
        [9.e+00, 9.e-02]]])

Здесь A[..., None] имеет форму (3, 3, 1), а C.squeeze() просто отменяет это избыточное ведущее одноэлементное измерение и придает ему форму (3,2) Они передают в форму (3, 3, 2). MATLAB и numpy по-разному интерпретируют многомерные массивы, что объясняет, почему repr выше соответствует трем массивам формы (3,2), тогда как MATLAB показывает два массива формы (3,3). Но на самом деле это тот же массив:

>>> D[..., 0]
array([[100.,  20.,   3.],
       [400.,  50.,   6.],
       [700.,  80.,   9.]])

>>> D[..., 1]
array([[1.  , 0.2 , 0.03],
       [4.  , 0.5 , 0.06],
       [7.  , 0.8 , 0.09]])

Обратите внимание, что если вы сохраняете порядок MATLAB в своем коде numpy, возможно, вы захотите использовать разметку fortran в своих массивах, иначе у вас будут "быстрые" оси в неоптимальных местах кода numpy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...