使用numpy绘制趋势线时出现datetime64与float64类型报错如何解决
报错原因
ufunc 'add' cannot use operands with types dtype('<M8[ns]') and dtype('float64') 是类型不匹配错误:numpy.polyfit 做线性拟合时仅接受数值型输入,你代码里传入的x是pandas解析得到的datetime64[ns](即<M8[ns])时间戳类型,无法直接和浮点数做拟合运算,最终触发报错。
修复方法
拟合前把时间列转换为数值类型即可,绘图时仍保留原始时间列作为x轴,不会影响时间格式的正常显示。
修正后的可运行代码:
import pandas as pd import matplotlib.pyplot as plt import numpy as num %matplotlib inline df = pd.read_excel(r'C:\Users\hussa\Downloads\Bo Karar.xlsx', "Data2") x = df['DataA'] y = df['DataB'] # 将时间戳转换为int64格式的纳秒级时间戳(数值类型,适配polyfit输入要求) x_fit = x.values.astype("int64") # 执行一阶线性拟合 z = num.polyfit(x_fit, y, 1) p = num.poly1d(z) plt.figure() plt.plot(x, y, label="原始数据") # 趋势线计算传入数值型x,绘图x轴仍使用原始时间序列 plt.plot(x, p(x_fit), color="red", linestyle="--", label="线性趋势线") plt.legend() # 自动旋转x轴时间标签,避免文字重叠 plt.gcf().autofmt_xdate() plt.show()
更简便的适配场景
如果你的数据是等时间间隔采样(从样例数据看每10秒采集1条,符合这个特征),可以直接用数据的行序号作为拟合输入,不需要做时间格式转换:
# 生成从0开始的行序号作为拟合用x轴 x_seq = num.arange(len(df)) z = num.polyfit(x_seq, y, 1) p = num.poly1d(z) # 绘图时x轴仍传入原始时间列即可 plt.plot(x, p(x_seq), color="red", linestyle="--")
这种写法计算更简单,还能避免大数值时间戳带来的拟合精度损耗,适合固定采样频率的时序数据场景。
内容的提问来源于stack exchange,提问作者Hussain Rahma
相关产品推荐
相关产品推荐

