【问题标题】:Graph a custom function in python在 python 中绘制一个自定义函数
【发布时间】:2018-07-07 12:02:03
【问题描述】:

我想绘制一个自定义函数,包括minmax

import numpy as np
import matplotlib.pyplot as plt

f = lambda x: max(0, x)
x = np.linspace(-10, 10)
y = f(x)

plt.plot(x, y)
plt.show()

结果:

ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()

欢迎大家帮忙

【问题讨论】:

标签: python numpy matplotlib


【解决方案1】:

您可以只使用列表推导来为每个 x 值获取相应的 y 值。

import numpy as np
import matplotlib.pyplot as plt

f = lambda x: max(0, x)
x = np.linspace(-10, 10)
y = [f(i) for i in x]

plt.plot(x, y)
plt.show()

【讨论】:

    【解决方案2】:

    使用矢量化 np.clip() 而不是 f - 这样您可以一步设置下限 (a_min) 和上限 (a_max) 边界:

    y = np.clip(x, a_min=0, a_max=None)
    

    或尝试矢量化您的标量函数:

    In [146]: x = np.linspace(-1000, 1000, 10**6)
    
    In [147]: x.shape
    Out[147]: (1000000,)
    
    In [148]: vf = np.vectorize(f)
    
    In [149]: %timeit [f(i) for i in x]
    1.46 s ± 5.42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [150]: %timeit vf(x)
    1.03 s ± 8.73 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

    • 对于大问题,无疑比我的列表比较快,但它是针对这个特定问题的优化,而不是一般的lambda
    • 谢谢,我最终的自定义函数不仅基于min/max,还包含min/max
    • @alex,我建议你发布你的函数——如果它可以以一种使用快速(向量化)ufunc的方式向量化——与列表理解方法相比,它可能要快得多。 .
    • @roganjosh,对于小型数组,列表理解可能更快;-)
    【解决方案3】:

    np.maximum代替max

    from matplotlib import pyplot as plt
    import numpy as np
    
    f = lambda x: np.maximum(0, x)
    x = np.linspace(-10,10)
    y = f(x)
    
    plt.plot(x,y)
    plt.show()
    

    编辑

    对于更复杂的函数,请注意您打算使用的函数的 numpy 等效项。大多数情况下,名称与math 模块中的名称相同,例如math.sin 将变为 np.sin 等。但是,如示例中所示,max 应替换为 np.maximum 而不是 np.max,后者返回 np.ndarray 的最大值。

    【讨论】:

    • 这是针对特定问题的最优雅的 IMO 解决方案,但问题是“在 python 中绘制自定义函数”,这只是解决了 OP 给出的单一案例。
    • @roganjosh 非常正确,但另一方面,numpy 提供了许多数学函数的矢量化版本。至少math中的所有函数也都定义在numpy中,所以这个例子很容易扩展。
    • 这个想法当然是用np.maximum替换函数中的所有max。有趣的是np.clip 似乎比np.maximum 快一点。在初始函数上使用 np.vectorize 比任何 numpy 函数慢 100 倍。
    • @ImportanceOfBeingErnest 难道np.maximumnp.minimum 是使用np.clip 实现的吗?这可以解释更好的性能。
    • 我不知道。到目前为止,最快的解决方案是就地比较,def f(x): x[x<=0] = 0; return x
    【解决方案4】:

    我发现定义一个可以使用一行代码调用的函数很有用,所以现在我可以绘制任何函数(假设调用的组件是有效的,例如日志加载为“来自数学导入日志”,或者是表示为“math.log”,并且该函数可以在指定范围内进行评估):

    import matplotlib.pyplot as plt   #; plt.rcdefaults()
    import numpy as np
    from math import log
    
    def plot_func(x,f):
      # x = tuple defining range of x
      # f = string defining function to plot, in terms of x
      x = np.linspace(x[0],x[1],201)
      y = list(map(lambda x: eval(f), x))
      plt.close()
      plt.title('f(x) = ' + f)
      plt.plot(x,y, 'b')
    
    plot_func(x=(0, 1), f = '60 * (x**3) * (1-x)**2') 
    

    生成:

    避免对要绘制的函数进行正式定义,并且能够重用它来绘制任何东西,只需一条简单的线进行调整。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多