Jupyter Notebook实现Butterworth滤波器遇plt.plot报错求助
解决Jupyter Notebook中plt.plot的TypeError问题
可能的触发原因
time或sensor_data是多维numpy数组(比如形状为(1838,1)的二维数组),而非plt.plot要求的一维序列- 代码中误将numpy数组当作字典的键使用(字典键必须是可哈希类型,而numpy数组不可哈希)
- 读取数据时错误获取了DataFrame对象(比如用
df[['Euclidian Norm']]而非df['Euclidian Norm']),导致sensor_data不是一维序列
分步解决方案
1. 检查并修正数据维度
先打印变量的类型和形状,确认是否为一维结构:
print(type(time), time.shape) print(type(sensor_data), sensor_data.shape)
如果输出显示为二维数组(比如(1838,1)),用以下方法转成一维:
# 方法1:使用ravel() time = time.ravel() sensor_data = sensor_data.ravel() # 方法2:使用flatten() time = time.flatten() sensor_data = sensor_data.flatten()
如果是读取数据时误获取了DataFrame,改成以下方式提取数据:
# 从DataFrame中提取单列转为numpy一维数组 sensor_data = df['Euclidian Norm'].values
2. 排查字典键误用问题
检查代码中是否存在some_dict[time]或some_dict[sensor_data]这类写法,numpy数组不能作为字典键。如果必须用数组相关值当键,可将其转为元组:
# 将数组转为元组后作为字典键 some_dict[tuple(time)] = target_value
3. 完整的Butterworth滤波参考代码
以下是一套完整的读取数据、滤波、绘图流程,可直接参考:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.signal import butter, filtfilt # 读取CSV数据 df = pd.read_csv('Samples.csv') # 生成时间轴(若无单独时间列,用数据行号代替) time = np.arange(len(df)) # 提取目标列数据 sensor_data = df['Euclidian Norm'].values # 定义低通Butterworth滤波器 def butter_lowpass_filter(data, cutoff, fs, order=5): nyq_freq = 0.5 * fs normalized_cutoff = cutoff / nyq_freq b, a = butter(order, normalized_cutoff, btype='low', analog=False) filtered_data = filtfilt(b, a, data) return filtered_data # 配置滤波器参数(按需调整) sampling_freq = 100 # 采样频率(Hz) cutoff_freq = 10 # 截止频率(Hz) filter_order = 4 # 滤波器阶数 # 执行滤波 filtered_data = butter_lowpass_filter(sensor_data, cutoff_freq, sampling_freq, filter_order) # 绘制对比图 plt.figure(figsize=(10, 6)) plt.plot(time, sensor_data, label='原始数据', alpha=0.6) plt.plot(time, filtered_data, label='滤波后数据', linewidth=2) plt.xlabel('时间') plt.ylabel('Euclidian Norm') plt.legend() plt.show()
额外注意事项
- 若未安装
scipy,在Jupyter中执行!pip install scipy完成安装 - 数据存在缺失值时,先执行
df = df.dropna(subset=['Euclidian Norm'])处理缺失值,避免滤波出错
内容的提问来源于stack exchange,提问作者user15841461
相关产品推荐
相关产品推荐

