Numpy:计算具有无限个变量的函数输出矩阵的优雅解决方案



我整个周末都在寻找一个更优雅(阅读:没有手动 for 循环编程(的解决方案来解决以下问题:

假设我们有一个具有无限数量的输入的自定义函数 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 的答案使用不同的路径产生相同的结果。

谢谢大家!堆栈溢出规则!

网格可以帮助您创建所有对,而不仅仅是将它们相加。作为奖励,它可以扩展到更多维度:

>>> 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]]])

编辑后,对网格进行任意操作

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

其中f必须采用一个*args参数或等于len(arrays)的参数数量,因此 meshOperation(f, x, y( 在最后一个示例中有效。

您似乎正在寻找点积的应用程序:

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 个维度(如矩阵对象(的内容(如矩阵对象(时才有效,其中一个是单例维度。然后转置其中一个,点积可以准确地为您提供所需的内容。

我建议使用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)))

最新更新