【问题标题】:Vectorizing a function (Python)向量化函数(Python)
【发布时间】:2013-10-09 00:15:40
【问题描述】:

我是 python 新手,正在尝试进行硬件分配,但它不断向我抛出此错误(在 iPython Notebook 中):

"TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'float'"

这是我试图模仿的公式:h(x)=(1/√2π)*e^−(1/2)^x^2

import numpy as np
import math
from math import *


def h_scalar(x):
    return (1 / sqrt(2 * pi)) * exp(-.50** x ** 2.00)

我正在努力得到和我老师一样的结果。

l = [-10.0, -1.0, 0.0, 1.0, 10.0] #
print h_scalar(l)
>>> [1.4867195147342977e-06, 0.24197072451914337, 0.3989422804014327,
0.24197072451914337, 1.4867195147342977e-06]

这是老师的问题:

首先,编写一个名为 h_scalar 的函数。该函数应该期望一个列表(或者通常是一个可迭代的项目)。它将期望列表包含浮点值。它应该返回一个新的浮点数列表,这些浮点数是输入列表中每个 x 值的 h(x)。您应该将函数命名为 h_scalar()

【问题讨论】:

  • 1.) 你的指数应该是-.50 * x ** 2.00。 2.) 您不能在标准 python 数组中广播像 **2.00 这样的操作。为此,请将x 转换为np.array。 3.) 如果您不想使用 numpy,请考虑使用for 循环来计算x 中每个元素的公式。将这些值存储在另一个数组中,然后将其返回。或者,使用列表推导。

标签: python numpy scipy vectorization scalar


【解决方案1】:

将 numpy 导入为 np 导入数学 从数学导入 *

定义 h_scalar(x): return (1 / sqrt(2 * pi)) * exp(-.50** x ** 2.00)

l = [-10.0, -1.0, 0.0, 1.0, 10.0]

h_scalar = np.vectorize(h_scalar) ## 你的代码中缺少这一行

打印 h_scalar(l)

【讨论】:

    【解决方案2】:

    您将使用numpysqrtexp 获得更好的性能,它们将按元素进行操作:

    import numpy as np
    from numpy import sqrt, exp, pi
    def h_scalar(x):
        x = np.array(x)
        return (1/sqrt(2*pi)) * exp(-0.50*x**2)
    

    你可以像这样使用它:

    x = [-10.0, -1.0, 0.0, 1.0, 10.0]
    h_scalar(x)
    

    【讨论】:

    • +1 这是迄今为止唯一从矢量化中获得适当性能优势的解决方案
    • 为了满足输入是一个列表(或任何可迭代)的要求,您应该插入x=np.array(x, copy=False)作为函数h_scalar的第一行。
    • @Dave,谢谢!我没有足够重视这个要求!在这种情况下,我认为您无法避免复制...
    【解决方案3】:

    您正在尝试对列表而不是列表项使用电源。我在这里可能有确切的功能错误,但尝试这样的方法来获取一个列表并返回一个列表。

    def h_scalar(x):
        return [(1/sqrt(2*pi))*exp(-.50 ** i ** 2.0) for i in x]
    

    我不确定你有正确的公式,你能重新格式化吗?

    In [14]: h_scalar(l)                                              
    Out[14]: 
    [0.3989422804014327,                                              
     0.24197072451914337,                                             
     0.14676266317373993,                                             
     0.24197072451914337,                                             
     0.3989422804014327]
    

    【讨论】:

    • 谢谢,我不知道我在这样做。我现在可以接收输出,但它与我的老师不匹配。我的输出现在是 “[0.3989422804014327,0.24197072451914337,0.14676266317373993,0.24197072451914337,0.3989422804014327]”,而我的老师的是 “[1.4867195147342977e-06,0.24197072451914337,0.3989422804014327,0.24197072451914337,1.4867195147342977e-06]” 我在计算什么不对还是? SPAN >
    • list comprehension 像 svk 和 Piotr 指出是一种方法。就像我说的,你会想仔细检查你的方程式,但我无法从你的格式中看出你想要得到什么。
    • 这看起来像你原来的等式吗:link
    【解决方案4】:

    要对列表(或另一个可迭代对象)中的所有项目执行操作,从操作的返回值创建一个新列表,您可以执行以下操作:

    >>> l = [1,2,3,4,5]
    >>> l2 = [ 2 * x for x in l ]
    >>> print l2
    [2, 4, 6, 8, 10]
    

    这里第二行使用的 Python 语言功能称为list comprehension,它非常适合您布置的家庭作业。

    【讨论】:

      【解决方案5】:

      如果您想使用numpy.vectorize,这是一种选择:

      >>> import numpy as np
      >>> h_scalar = np.vectorize(lambda x: (1 / np.sqrt(2 * np.pi)) * np.exp( -.50** x ** 2.00 ))
      >>> l = np.array([-10.0, -1.0, 0.0, 1.0, 10.0])
      >>> h_scalar(l)
      

      【讨论】:

      • 请记住,np.vectorize 与简单的列表理解相比并没有真正提供任何性能优势 - 您最终仍会在 Python 而不是 C 中循环
      【解决方案6】:

      你想要的是list comprehension

      像这样:

      def h_scalar(sca):
          return [(1 / sqrt(2 * pi)) * exp(-.50** x ** 2.00) for x in sca]
      

      【讨论】:

        猜你喜欢
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        • 2017-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-16
        相关资源
        最近更新 更多