我整个周末都在寻找一个更优雅(阅读:没有手动 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)))