Python处理G力CSV数据:gFy列格式转换与峰值检测问题求助
解决KeyError问题及实现G力数据峰值检测
一、修复KeyError: 'gFy'
出现该错误的核心原因是列名匹配异常或CSV读取参数错误,以下是针对性解决方案:
1. 清理列名隐藏空格/特殊字符
你打印df.columns.values看到列名存在,但可能列名前后带有空格(如' gFy'或'gFy ')或不可见字符。先统一清理所有列名:
df.columns = df.columns.str.strip()
之后再尝试访问df['gFy']即可匹配到正确列。
2. 修正CSV分隔符参数
你的代码使用sep='\t'(制表符分隔),但注释提到“split column names by semicolon”,说明实际文件大概率是分号分隔。修改读取逻辑:
# 基础分号分隔 df = pd.read_csv('G-forceData.csv', sep=';') # 若列名与值之间带有空格,用正则兼容 df = pd.read_csv('G-forceData.csv', sep='\s*;\s*', engine='python')
3. 直接用decimal参数处理逗号小数
无需手动替换逗号,read_csv支持指定小数分隔符,一步完成数值类型转换:
df = pd.read_csv('G-forceData.csv', sep=';', decimal=',') df.columns = df.columns.str.strip() gFy = df['gFy'].values # 直接转为numpy数组,无需额外类型转换
二、实现时段峰值检测
你之前用直方图的方式是统计数据分布峰值,并非时间序列的时段局部峰值。以下是两种实用实现方案:
方法1:使用scipy.signal.find_peaks(推荐)
该方法内置峰值检测逻辑,可灵活过滤噪声:
import pandas as pd import numpy as np from scipy.signal import find_peaks # 读取并预处理数据 df = pd.read_csv('G-forceData.csv', sep=';', decimal=',') df.columns = df.columns.str.strip() # 检测gFy的正向峰值:height设最小峰值高度,distance设峰值最小间距 peaks, properties = find_peaks(df['gFy'], height=0.003, distance=10) peak_data = df.loc[peaks, ['time', 'gFy']] print("正向峰值:") print(peak_data) # 检测谷值(负峰值):对gFy取反后检测 valleys, val_props = find_peaks(-df['gFy'], height=0.003, distance=10) valley_data = df.loc[valleys, ['time', 'gFy']] print("\n负向谷值:") print(valley_data)
方法2:手动差分法(无需依赖scipy)
通过二阶差分判断局部峰值位置:
import pandas as pd import numpy as np # 读取预处理数据 df = pd.read_csv('G-forceData.csv', sep=';', decimal=',') df.columns = df.columns.str.strip() # 计算二阶差分,定位峰值点 first_diff = np.diff(df['gFy']) second_diff = np.diff(first_diff) # 二阶差分由正转负的位置即为峰值(索引需+1补平差分后的长度损失) peak_indices = np.where(second_diff < 0)[0] + 1 # 过滤密集噪声峰值,设置最小间距5个数据点 peak_indices = peak_indices[np.diff(peak_indices, prepend=-10) > 5] peak_data = df.loc[peak_indices, ['time', 'gFy']] print("检测到的峰值:") print(peak_data)
参数说明
height:过滤低于该值的小波动噪声,可根据你数据的±0.005范围调整(如设为0.003)。distance:限制两个峰值的最小数据点间距,避免检测到连续噪声。
内容的提问来源于stack exchange,提问作者Mathijs Follon
相关产品推荐
相关产品推荐

