Преобразование bsxfun с @times в numpy

это код, который у меня есть в Октаве:

sum(bsxfun(@times, X*Y, X), 2)

часть bsxfun кода производит умножение по элементам, поэтому я подумал, что numpy.multiply(X*Y, X) будет делать трюк, но я получил исключение. Когда я провел небольшое исследование, я обнаружил, что умножение по элементам не будет работать на массивах Python (в частности, если X и Y имеют тип "numpy.ndarray"). Поэтому мне было интересно, может ли кто-нибудь объяснить это немного больше-т. е. будет ли тип кастинга работать с другим типом объекта? Код Октавы работает, поэтому я знаю, что у меня нет ошибки линейной алгебры. Я предполагаю, что bsxfun и numpy.умножение на самом деле не эквивалентно, но я не уверен, почему так любые объяснения были бы отличными.

я смог найти сайт! это дает Октаву для преобразования функций Matlab, но в моем случае это не помогло.

2 ответов


bsxfun в MATLAB стенд для двоичного одноэлементного расширения, в numpy это называется вещанием и должно происходить автоматически. Решение будет зависеть от размеров вашего X, т. е. это строка или вектор-столбец, но этот ответ показывает один из способов сделать это:

Как умножить массив numpy 2D с массивом numpy 1D?

Я думаю, что проблема здесь в том, что вещание требует, чтобы одно из измерений было 1 и, в отличие от Matlab, numpy кажется дифференцировать между вектором 1-мерного элемента 2 и 2-мерным элементом 2, т. е. разность между матрицей формы (2,) и формы (2,1), вам нужно последнее для трансляции.


для тех, кто не знает Numpy, я думаю, стоит отметить, что эквивалент октавы (и Matlab) * оператор (умножение матриц) составляет numpy.dot (и, возможно, numpy.outer). И NumPy это * оператор похож на bsxfun(@times,...) в Октаве, что само по себе является обобщением .*.

в Октаве, при применении bsxfun, есть неявные одноэлементные размеры справа от "истинного" размера операндов; то есть n1 x n2 x n3 массив можно рассматривать as n1 x n2 x n3 x 1 x 1 x 1 x.... В Numpy неявные одноэлементные измерения находятся слева; поэтому m1 x m2 x m3 можно рассматривать как ... x 1 x 1 x m1 x m2 x m3. Это имеет значение при рассмотрении размеров операндов: в Октаве, bsxfun(@times,a,b) будет работать, если a 2 x 3 x 4 а b-это 2 x 3. В Numpy нельзя было умножить два таких массива, но один мог бы умножить на 2 x 3 x 4 и 3 x 4 массив.

наконец, bsxfun(@times, X*Y, X) в октаву, вероятно, будет выглядеть что-то вроде numpy.dot(X,Y) * X. Есть еще несколько подводных камней: например, если вы ожидаете внешнего продукта (то есть в Октаве X-вектор столбца, Y-вектор строки), вы можете посмотреть на использование numpy.outer вместо этого или будьте осторожны с формой X и Y.