Применить пользовательскую функцию к 2 или более строк (или столбцов) в NumPy - PullRequest
0 голосов
/ 06 декабря 2018

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

a) Как новичок, я не совсем уверен, что делает такая операция, как A[:,None,:].

б) Эта операция не работает в моем случае.Пожалуйста, см. Ниже.

Предположим, что Матрица М имеет вид:

import numpy as np
M = np.array([[8, 3, 2],
              [6, 1, 2],
              [1, 2, 4]])

Теперь я бы хотел вычислить произведение комбинации всех трех строк.Для этого я создал пользовательскую функцию.Фактическая работа функции может отличаться от умножения.Умножение является только примером.

def myf(a,b): return(a*b) 

Я взял numpy массива продукта в качестве примера.Фактическая пользовательская функция может отличаться, но независимо от операции, функция всегда будет возвращать массив numpy.то есть он займет два одинаковых по размеру numpy 1-D массива и вернет 1-D массив.В myf я предполагаю, что a и b каждый np.array.

Я хочу иметь возможность применить пользовательскую функцию к любым двум строкам или столбцам или даже трем строкам (рекурсивное применениефункция).

Ожидаемый результат после рекурсивного умножения двух строк:

Если я применяю парную операцию строки:

[[48,3,4],
 [6,2,8],
 [8,6,8]]

ИЛИ (Порядок применения пользовательской функции неЭто не имеет значения. Следовательно, фактическое положение строк в выходной матрице не будет иметь значения. Ниже матрицы также будет хорошо.)

[[6,2,8],
 [48,3,4],  #row1 and 2 are swapped
 [8,6,8]]

Аналогично, если я применю парную операцию к столбцам, я быget

[[24, 6, 16]
 [6,  2, 12] 
 [2,  8, 4]]

Точно так же, если бы я применил пользовательскую функцию ко всем трем строкам, я получил бы:

[48,6,16] #row-wise

ИЛИ

[48,12,8] #column-wise

Я попробовал несколько подходовпосле прочтения SO:

1:

vf=np.vectorize(myf)
vf(M,M)

Однако вышеупомянутая функция применяет пользовательскую функцию поэлементно, а не по строкам или столбцам.

2:

Я также пробовал:

M[:,None,:].dot(M) #dot mimics multiplication. Python wouldn't accept `*`

Есть две проблемы с этим:

a) Я не знаю, что выводis.

b) Я не могу применить пользовательскую функцию.

Может кто-нибудь помочь мне?Буду признателен за любую помощь.

Я открыт для numpy и scipy.


Некоторые эксперты запрашивают желаемый результат.Предположим, что желаемый результат равен [[48,3,4], [6,2,8], [8,6,8]].

Однако я был бы признателен за некоторые рекомендации по настройке решения для 2 или более столбцов и 2 или более строк.

1 Ответ

0 голосов
/ 06 декабря 2018

Вы можете просто повернуть ось вдоль 0 -ой оси

np.roll(M, -1, axis=0)
# array([[6, 1, 2],
#        [1, 2, 4],
#        [8, 3, 2]])

и умножить результат на исходный массив

M * np.roll(M, -1, axis=0)
# array([[48,  3,  4],
#        [ 6,  2,  8],
#        [ 8,  6,  8]])

Если вы хотите включить более двухстрок, вы можете свернуть его более одного раза:

M * np.roll(M, -1, axis=0) * np.roll(M, -2, axis=0)
# array([[48,  6, 16],
#        [48,  6, 16],
#        [48,  6, 16]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...