【问题标题】:Numpy: Elegant solution to calculating output matrix of function with indefinite number of variablesNumpy:计算变量数不定的函数输出矩阵的优雅解决方案
【发布时间】:2020-06-01 03:59:57
【问题描述】:

我整个周末都在寻找更优雅(阅读:无需手动 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:接受的答案按预期工作。链接到stackoverflow.com/a/32742943/6075699 的 Dishin H Goyani 的答案使用不同的路径产生相同的结果。

谢谢大家! Stackoverflow 规则!

【问题讨论】:

标签: python numpy


【解决方案1】:

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

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

【讨论】:

  • 我不明白,这对于具有更高复杂性的自定义函数如何工作?请看我的编辑!
  • 即使您的第一个单元格也是错误的,除非我误读了您打算如何将其弄平。根据 OP,第一个元素不应该是 1 + 1。
【解决方案2】:

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

>>> 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) 在您的最后一个示例中有效。

【讨论】:

  • 编辑后:这绝对适用于 2D 问题,对于 3D 我将尝试下一步。奇怪的是,它会切换输入顺序,因此您必须转置输出数组。
  • @olivherbst 奇怪和预期是您的品味和经验的问题。在结果中使用.T 进行转置。
【解决方案3】:

我建议numpy array broadcasting

例子:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    相关资源
    最近更新 更多