【问题标题】:Matplotlib: TypeError: can't multiply sequence by non-int of type 'numpy.float64'Matplotlib:TypeError:不能将序列乘以“numpy.float64”类型的非整数
【发布时间】:2014-12-28 16:57:36
【问题描述】:

我正在尝试将一条最适合我的 matplotlib 图表的线性线拟合。我不断收到 x 和 y 第一维不同的错误。但是它们的长度都是 15。我做错了什么?

import matplotlib.pyplot as plt
from scipy import stats
import numpy as np

x = [0.46,0.59,0.68,0.99,0.39,0.31,1.09,0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78]
y = [0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,0.478,0.335,0.365,0.424,0.390,0.585,0.511]
xerr = [0.01]*15
yerr = [0.001]*15

plt.rc('font', family='serif', size=13)
m, b = np.polyfit(x, y, 1)
plt.plot(x,y,'s',color='#0066FF')
plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
plt.xlabel('$\Delta t$ $(s)$',fontsize=20)
plt.ylabel('$\Delta p$ $(hPa)$',fontsize=20)
plt.autoscale(enable=True, axis=u'both', tight=False)
plt.grid(False)
plt.xlim(0.2,1.2)
plt.ylim(0,0.8)
plt.show()

错误

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_34116/1820029981.py in <module>
      7 m, b = np.polyfit(x, y, 1)
      8 plt.plot(x,y,'s',color='#0066FF')
----> 9 plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
     10 plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
     11 plt.xlabel('$\Delta t$ $(s)$',fontsize=20)

TypeError: can't multiply sequence by non-int of type 'numpy.float64'

【问题讨论】:

    标签: python numpy matplotlib


    【解决方案1】:

    您应该创建 xy numpy 数组,而不是列表:

    x = np.array([0.46,0.59,0.68,0.99,0.39,0.31,1.09,
                  0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78])
    y = np.array([0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,
                  0.478,0.335,0.365,0.424,0.390,0.585,0.511])
    

    通过此更改,它会产生预期的情节。如果它们是列表,m * x 将不会产生您期望的结果,而是一个空列表。请注意,mnumpy.float64 标量,而不是标准 Python float

    我实际上认为 Numpy 的这种行为有点可疑。在普通 Python 中,将列表与整数相乘只会重复列表:

    In [42]: 2 * [1, 2, 3]
    Out[42]: [1, 2, 3, 1, 2, 3]
    

    将列表与浮点数相乘会产生错误(我认为应该如此):

    In [43]: 1.5 * [1, 2, 3]
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-43-d710bb467cdd> in <module>()
    ----> 1 1.5 * [1, 2, 3]
    TypeError: can't multiply sequence by non-int of type 'float'
    

    奇怪的是,将 Python 列表与 Numpy 标量相乘显然有效:

    In [45]: np.float64(0.5) * [1, 2, 3]
    Out[45]: []
    
    In [46]: np.float64(1.5) * [1, 2, 3]
    Out[46]: [1, 2, 3]
    
    In [47]: np.float64(2.5) * [1, 2, 3]
    Out[47]: [1, 2, 3, 1, 2, 3]
    

    所以看起来float被截断为int,之后你会得到重复列表的标准Python行为,这是非常出乎意料的行为。最好的办法是提出一个错误(这样您就可以自己发现问题,而不必在 Stackoverflow 上提出您的问题)或只显示预期的元素乘法(您的代码将在其中工作) .有趣的是,列表和 Numpy 标量之间的加法确实有效:

    In [69]: np.float64(0.123) + [1, 2, 3]
    Out[69]: array([ 1.123,  2.123,  3.123])
    

    【讨论】:

    • 等等我不明白,有什么问题?只是转换为 np.array 的解决问题?
    • @CharlieParker:是的,它有效。这里没什么奇怪的,让我解释一下。当 OP 执行 m,b=np.polyfit(x,y,1) 时,您会在这里得到 m 为 float64 值,例如上述情况下的 m=0.642。现在,当您尝试将浮点数 m 与列表 x 相乘时,最终会得到一个空列表 []。这是因为要将列表的每个元素与一个值相乘,您需要将列表转换为numpy array 或使用内置的map 函数。请参阅this answer 了解更多信息。
    【解决方案2】:

    将您的列表更改为numpy 数组就可以了!

    import matplotlib.pyplot as plt
    from scipy import stats
    import numpy as np 
    
    x = np.array([0.46,0.59,0.68,0.99,0.39,0.31,1.09,0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78]) # x is a numpy array now
    y = np.array([0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,0.478,0.335,0.365,0.424,0.390,0.585,0.511]) # y is a numpy array now
    xerr = [0.01]*15
    yerr = [0.001]*15
    
    plt.rc('font', family='serif', size=13)
    m, b = np.polyfit(x, y, 1)
    plt.plot(x,y,'s',color='#0066FF')
    plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
    plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
    plt.xlabel('$\Delta t$ $(s)$',fontsize=20)
    plt.ylabel('$\Delta p$ $(hPa)$',fontsize=20)
    plt.autoscale(enable=True, axis=u'both', tight=False)
    plt.grid(False)
    plt.xlim(0.2,1.2)
    plt.ylim(0,0.8)
    plt.show()
    

    【讨论】:

    • @CharlieParker:是的,它有效。这里没什么奇怪的,让我解释一下。当 OP 执行 m,b=np.polyfit(x,y,1) 时,您会在这里得到 m 为 float64 值,例如上述情况下的 m=0.642。现在,当您尝试将浮点数 m 与列表 x 相乘时,最终会得到一个空列表 []。这是因为要将列表的每个元素与一个值相乘,您需要将列表转换为numpy array 或使用内置的map 函数。请参阅this answer 了解更多信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多