TypeError:尝试绘制函数时,只能将大小为 1 的数组转换为 Python 标量

Posted

技术标签:

【中文标题】TypeError:尝试绘制函数时,只能将大小为 1 的数组转换为 Python 标量【英文标题】:TypeError: only size-1 arrays can be converted to Python scalars when trying to plot a function 【发布时间】:2021-11-29 16:37:52 【问题描述】:

我有当前代码:

from math import cos, sin, pi
import numpy as np
import matplotlib.pyplot as plt

def f(x):
    
    values = []
    s = 0
    for n in range(1, 6, 1):
        s += -((2/(n*pi))*(((cos((n*pi)/2))-1)*(sin((n/2)*x))))
        values.append(s)
        
    return values

x = np.linspace(-2*pi, 6*pi, 500)
plt.plot(f(x))

我应该绘制 f(x),但是当我运行代码时,我得到了这个错误:

TypeError:只有 size-1 的数组可以转换为 Python 标量

关于我做错了什么有什么想法吗?

任何帮助将不胜感激!

【问题讨论】:

这是一个从您的f 实施中冒出来的错误。 (你可以单独运行f,而不用绘图,看看发生了什么。)s 应该代表什么? @navneethc 哦,我可能应该提到这一点。在前一个任务中,我们被告知在 python 中实现 f(x) 的总和(表达式 -((2/(npi))*(((cos((npi)/2 ))-1)*(sin((n/2)*x)))) 在 n 的范围内是我想要求和的)。我还尝试设置“x = 5”,然后打印“f(x)”,这给了我一个包含五个总和的列表。这可能是一个混乱的答案,但我对编码很陌生,而且对术语也很陌生。希望它仍然可以解决问题。 是的,x=5 有效,因为您可以在intfloat 等上应用math.sinmath.cos。一个标量,一个单一的数值,基本上。而在您的代码中,您传递的是整个 numpy 数组;这是行不通的,因为x,如上所述,其中有 500 个点。错误消息说,您可以使用具有 1 个标量但不超过该标量的数组。 了解您尝试编写的实际数学过程会有所帮助。 @navneethc 添加了一个图片链接,向您展示它的样子 【参考方案1】:

我认为公式中的x 值仅适用于x 的一个值,并且由于您有多个x 以列表的形式存在,因此您必须遍历它们中的每一个(例如,使用for xval in x:),执行计算并将计算值附加到values列表

from math import cos, sin, pi
import numpy as np
import matplotlib.pyplot as plt

def f(x):
    values = []
    for xval in x:
        s = 0
        for n in range(1, 6, 1):
            s += -((2/(n*pi))*(((cos((n*pi)/2))-1)*(sin((n/2)*xval))))
        values.append(s * -1)
        
    return values

x = np.linspace(-2*pi, 6*pi, 500)
plt.plot(f(x))
plt.show()

【讨论】:

你完全正确!谢谢!【参考方案2】:

如果您是编程新手,这可能看起来与您现在正在做的有点不同,但是我基本上已经将函数拆分来解释每个组件的作用,更重要的是,使用了 numpy 的内置函数证明比嵌套循环更有效,尤其是当您的数据变大时。

要了解函数 f 发生了什么,请在 Python 中查找(列表)推导,但它基本上是用单行表示的 for 循环。

In [24]: import numpy as np
    ...: import matplotlib.pyplot as plt

In [25]: def summand(n, x):
    ...:     """ Return an array of `x`'s size for a given value of `n`.
    ...:     Each element of the array is a value of the function computed
    ...:     at a value in `x` with the given `n`.
    ...:     """
    ...:     return (2 / (n * np.pi)) * (np.cos(n * np.pi / 2) - 1) * np.sin(n * x / 2)
    ...:

In [26]: def f(x, N=5):
    ...:     """ Return the sum of the summands computed for
    ...:     values of `n` ranging from 1 to N+1 with a given array `x`
    ...:     """
    ...:     return sum(summand(n, x) for n in range(1, N+1))
    ...:

In [27]: x = np.linspace(-2*np.pi, 6*np.pi, 500)

In [28]: plt.plot(x, f(x))
Out[28]: [<matplotlib.lines.Line2D at 0x23e60b52a00>]

In [29]: plt.show()

【讨论】:

我会仔细阅读并尝试理解您的所作所为。感谢您的帮助!

以上是关于TypeError:尝试绘制函数时,只能将大小为 1 的数组转换为 Python 标量的主要内容,如果未能解决你的问题,请参考以下文章

绘制Vasicek模型。只能将大小为-1的数组转换为python标量

TypeError:在绘制 seaborn.regplot 时,无法根据规则“安全”将数组数据从 dtype('int64') 转换为 dtype('int32')

TypeError 使用 chaquopy 调用 python 函数

TypeError:使用 trapz 方法时,只能将 size-1 数组转换为 Python 标量

TypeError:在使用 Python 进行网络抓取时,只能将 str(而不是“列表”)连接到 str 错误

TypeError:只能将列表(不是“str”)连接到列表 -