Numpy: элегантное решение для расчета выходной матрицы функции с неопределенным числом переменных - PullRequest
1 голос
/ 17 февраля 2020

В течение всех выходных я искал более элегантное (читай: руководство по программированию для -l oop) нет решения следующей проблемы:

Предположим, у нас есть пользовательская функция f () с неопределенное количество входов. Для простоты, давайте начнем с двух:

def f(x,y):
    return x + y

Теперь я передаю массив с правильным количеством переменных этой функции:

x = np.array([x0, x1, x2, ..., xn])
y = np.array([y0, y1, y2, ..., yn])

Ответ, который я ищу:

z = np.array([[x0 + y0, x0 + y1, x0 + y2, ..., x0 + yn],
              [x1 + y0, x1 + y1, x1 + y2, ..., x1 + yn],
              [x2 + y0, x2 + y1, x2 + y2, ..., x2 + yn],
              ...])

Итак, в общем, я ищу функцию, в которую я могу передать другую пользовательскую функцию, которая затем вычисляет все возможные комбинации, без необходимости программировать смешное число циклов for.

Пожалуйста, помогите мне, улей!

Редактировать 1: пользовательская функция может иметь произвольную сложность. Из моей реальной проблемы это один пример:

def f(x, y):
    return 1 - (x/2)**y*binom(y, y/2)

Редактировать 2: принятый ответ работает как задумано. Ответ Dishin H Goyani, ссылающийся на stackoverflow.com / a / 32742943/6075699 , дает тот же результат, используя другой путь.

Спасибо всем! Правила переполнения стека!

Ответы [ 3 ]

1 голос
/ 17 февраля 2020
Сетка

Me sh может помочь вам создать все пары, а не просто суммировать их. В качестве бонуса его можно расширить до нескольких измерений:

>>> y = np.arange(1,5)
>>> x = np.arange(6,10)
>>> x
array([6, 7, 8, 9])
>>> y
array([1, 2, 3, 4])
>>> sum(np.meshgrid(x,y))
array([[ 7,  8,  9, 10],
       [ 8,  9, 10, 11],
       [ 9, 10, 11, 12],
       [10, 11, 12, 13]])

Чтобы поместить это в функцию с неизвестным числом массивов:

def meshSum(*arrays):
    return sum(np.meshgrid(*arrays))

Пример с другим массивом:

>>> z = np.arange(11,15)
>>> def meshSum(*arrays):
...     return sum(np.meshgrid(*arrays))
...
>>> meshSum(x,y,z)
array([[[18, 19, 20, 21],
        [19, 20, 21, 22],
        [20, 21, 22, 23],
        [21, 22, 23, 24]],

       [[19, 20, 21, 22],
        [20, 21, 22, 23],
        [21, 22, 23, 24],
        [22, 23, 24, 25]],

       [[20, 21, 22, 23],
        [21, 22, 23, 24],
        [22, 23, 24, 25],
        [23, 24, 25, 26]],

       [[21, 22, 23, 24],
        [22, 23, 24, 25],
        [23, 24, 25, 26],
        [24, 25, 26, 27]]])

После вашего редактирования для произвольной операции на me sh

def meshOperation(f, *arrays):
    return f((*np.meshgrid(*arrays))

, где f должен принимать либо аргумент *args, либо число аргументы равны len(arrays), поэтому meshOperation (f, x, y) действителен в вашем последнем примере.

1 голос
/ 17 февраля 2020

Кажется, что вы ищете приложение точечного продукта:

In [1]: a = np.array([1, 2, 3, 4, 5, 6, 7])
In [2]: b = np.array([1, 2, 3, 4, 5, 6, 7])
In [3]: np.dot(np.matrix(a).T, np.matrix(b))
Out[3]: 
 matrix([[ 1,  2,  3,  4,  5,  6,  7],
         [ 2,  4,  6,  8, 10, 12, 14],
         [ 3,  6,  9, 12, 15, 18, 21],
         [ 4,  8, 12, 16, 20, 24, 28],
         [ 5, 10, 15, 20, 25, 30, 35],
         [ 6, 12, 18, 24, 30, 36, 42],
         [ 7, 14, 21, 28, 35, 42, 49]])

Это работает, только если вы преобразуете свой массив в нечто, имеющее 2 измерения (например, матричный объект), из которых один - одноэлементное измерение. Затем перенесите один из них, и скалярное произведение может дать вам именно то, что вам нужно.

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

Я предлагаю numpy массив вещания .

Пример:

import numpy as np

# initial arrays
x = np.arange(1, 15, 3)
y = np.arange(1, 6) + 100

# get them to 2d
x2 = np.atleast_2d(x)
y2 = np.atleast_2d(y).T  #y should be vertical

# simple stuff
print("sum:\n", x2 + y2)

# complicated stuff
print("complicated:\n", x2/(1+y2) + np.exp(-y2/(1+x2)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...