You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python检测电池电压数据循环且避免数据丢失?

电池电压循环检测方案

针对电池电压的循环检测,核心是基于电压的**趋势变化(上升/下降/平稳)**识别完整充放电周期,同时通过插值替代过滤来避免数据丢失。以下是具体实现步骤和代码:

步骤1:数据预处理(避免丢失数据)

先将时间列转为datetime类型,用线性插值填充缺失值,确保时间序列连续:

import pandas as pd
import plotly.express as px
import numpy as np

# 读取数据
dfm = pd.read_excel(r"C:\Users\Desktop\range\Battery Voltage.xlsx")

# 转换时间列并设置为索引,保证时序有序
dfm['date_time'] = pd.to_datetime(dfm['date_time'])
dfm = dfm.set_index('date_time').sort_index()

# 用线性插值填充缺失值(替代过滤,避免数据丢失)
dfm['External Voltage'] = dfm['External Voltage'].interpolate(method='linear')

步骤2:计算电压趋势(上升/下降/平稳)

通过计算相邻时刻的电压差分,结合噪声阈值判断每个数据点的趋势:

# 计算电压差分(当前值-前一个值)
dfm['voltage_diff'] = dfm['External Voltage'].diff()

# 设置噪声阈值(根据数据实际波动调整,示例为0.01V)
threshold = 0.01

# 标记每个点的趋势
dfm['trend'] = np.where(dfm['voltage_diff'] > threshold, '上升',
                        np.where(dfm['voltage_diff'] < -threshold, '下降', '平稳'))

# 处理第一个数据点的空值
dfm['trend'].fillna('平稳', inplace=True)

步骤3:合并连续的相同趋势段

将连续的相同趋势合并为区间,方便后续识别循环:

# 标记趋势段分组:趋势变化时分组编号+1
dfm['trend_group'] = (dfm['trend'] != dfm['trend'].shift(1)).cumsum()

# 统计每个趋势段的关键信息
trend_segments = dfm.groupby('trend_group').agg(
    start_time=('date_time', 'first'),
    end_time=('date_time', 'last'),
    trend=('trend', 'first'),
    avg_voltage=('External Voltage', 'mean'),
    duration=('date_time', lambda x: (x.max() - x.min()).total_seconds()/3600)  # 转换为小时
).reset_index()

步骤4:识别完整充放电循环

根据趋势序列(比如下降→平稳→上升→平稳)判定完整循环,也可根据实际数据调整循环判定逻辑:

# 提取趋势序列
trend_sequence = trend_segments['trend'].tolist()

# 检测符合"下降→平稳→上升→平稳"的完整循环
cycle_count = 0
cycle_intervals = []

for i in range(len(trend_sequence)-3):
    if (trend_sequence[i] == '下降' and 
        trend_sequence[i+1] == '平稳' and 
        trend_sequence[i+2] == '上升' and 
        trend_sequence[i+3] == '平稳'):
        cycle_count += 1
        cycle_intervals.append({
            'cycle_num': cycle_count,
            'start_time': trend_segments.loc[i, 'start_time'],
            'end_time': trend_segments.loc[i+3, 'end_time'],
            'min_voltage': dfm.loc[trend_segments.loc[i, 'start_time']:trend_segments.loc[i+3, 'end_time'], 'External Voltage'].min(),
            'max_voltage': dfm.loc[trend_segments.loc[i, 'start_time']:trend_segments.loc[i+3, 'end_time'], 'External Voltage'].max()
        })

# 转换为DataFrame查看结果
cycle_df = pd.DataFrame(cycle_intervals)
print(f"检测到的循环数量:{cycle_count}")
print(cycle_df)

步骤5:可视化循环标记

用Plotly在原始电压曲线上标记出每个循环区间:

# 绘制原始电压曲线
fig = px.line(dfm, x=dfm.index, y='External Voltage', title='电池电压与循环标记')

# 为每个循环添加区间高亮和标注
for idx, row in cycle_df.iterrows():
    fig.add_vrect(
        x0=row['start_time'], x1=row['end_time'],
        fillcolor=f'rgba(255, 0, 0, {0.1*(idx%5+1)})',
        annotation_text=f"循环{row['cycle_num']}",
        annotation_position="top left"
    )

fig.show()

关键说明

  • 阈值调整:threshold需根据数据实际波动情况修改,避免将噪声误判为趋势变化。
  • 循环定义:若你的循环是其他模式(比如直接下降→上升无静置),可修改循环检测的条件。
  • 数据保留:用线性插值替代过滤,最大程度保留原始数据的同时处理缺失值。

内容的提问来源于stack exchange,提问作者appu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:59:56