如何在Pandas DataFrame中按日分块处理电池充放电数据
分块处理CSV时电池充放电/容量计算逻辑出错(单天逻辑已验证)
背景与需求
我有一份记录电池每小时放电量、温度的CSV文件,时间规则是每天13:00为分界点:
- 前10小时(13:00 ~ 次日01:00):放电时段
- 后14小时(次日01:00 ~ 当日13:00):充电时段
需要完成以下计算:
- 计算每日放电时段(前10h)
Energy列的总和EnergySum,如果总和超过26就强制设为26 - 基于
EnergySum计算电池当前容量Cap - 添加
Charged列:放电时段固定为0;充电时段根据当前Cap补充至满电,只记录实际需要的补电量,补满后后续充电时段的Charged设为0 - 添加
Consumption列:逻辑和Charged完全一致,但计算依据是Electricity列
已验证的单天代码
单天24小时数据的计算逻辑完全正确,代码如下:
import pandas as pd # 单天24h数据示例 single_day_data = pd.DataFrame({ "Datetime": pd.date_range(start="2024-01-01 13:00", periods=24, freq="H"), "Energy": [3.2, 2.8, 3.0, 2.9, 3.1, 2.7, 3.3, 2.6, 3.0, 2.5] + [0]*14, "Temperature": [25]*24, "Electricity": [1.5, 1.4, 1.6, 1.5, 1.7, 1.3, 1.6, 1.2, 1.5, 1.1] + [0]*14 }) # 计算当日EnergySum discharge_period = single_day_data.iloc[:10] energy_sum = discharge_period["Energy"].sum() energy_sum = min(energy_sum, 26) # 假设满电容量为30,计算当前Cap(示例逻辑:满电减消耗) full_cap = 30 cap = full_cap - energy_sum # 添加Charged列 single_day_data["Charged"] = 0 remaining_charge = full_cap - cap for idx in range(10, 24): if remaining_charge <= 0: break # 示例:充电时段每小时最大补能2 charge_needed = min(remaining_charge, 2) single_day_data.loc[idx, "Charged"] = charge_needed remaining_charge -= charge_needed # 添加Consumption列(逻辑同Charged,基于Electricity) single_day_data["Consumption"] = 0 remaining_consumption = full_cap - cap for idx in range(10, 24): if remaining_consumption <= 0: break consume_needed = min(remaining_consumption, single_day_data.loc[idx, "Electricity"]) single_day_data.loc[idx, "Consumption"] = consume_needed remaining_consumption -= consume_needed print(single_day_data)
出错的分块处理代码
当用分块遍历整个CSV时,计算结果完全错误,核心问题是跨块的状态无法延续(比如上一块结束时的Cap无法传递到下一块),代码如下:
import pandas as pd chunk_size = 24 full_cap = 30 current_cap = full_cap # 初始化满电 for chunk in pd.read_csv("battery_data.csv", chunksize=chunk_size, parse_dates=["Datetime"]): # 计算当日EnergySum discharge_period = chunk.iloc[:10] energy_sum = discharge_period["Energy"].sum() energy_sum = min(energy_sum, 26) # 错误点:直接用满电减当日消耗,没有用上一块的剩余Cap current_cap = full_cap - energy_sum # 添加Charged列 chunk["Charged"] = 0 remaining_charge = full_cap - current_cap for idx in range(10, 24): if remaining_charge <= 0: break charge_needed = min(remaining_charge, 2) chunk.loc[chunk.index[idx], "Charged"] = charge_needed remaining_charge -= charge_needed # 添加Consumption列 chunk["Consumption"] = 0 remaining_consumption = full_cap - current_cap for idx in range(10, 24): if remaining_consumption <= 0: break consume_needed = min(remaining_consumption, chunk.loc[chunk.index[idx], "Electricity"]) chunk.loc[chunk.index[idx], "Consumption"] = consume_needed remaining_consumption -= consume_needed # 追加保存结果 chunk.to_csv("processed_battery_data.csv", mode="a", header=False, index=False)
数据集示例
CSV原始数据格式如下:
Datetime,Energy,Temperature,Electricity 2024-01-01 13:00:00,3.2,25,1.5 2024-01-01 14:00:00,2.8,26,1.4 2024-01-01 15:00:00,3.0,25,1.6 ... 2024-01-02 12:00:00,0,24,0 2024-01-02 13:00:00,2.9,25,1.5
预期输出示例
处理后的每条数据应包含新增列,示例如下:
| Datetime | Energy | Temperature | Electricity | EnergySum | Cap | Charged | Consumption |
|---|---|---|---|---|---|---|---|
| 2024-01-01 13:00:00 | 3.2 | 25 | 1.5 | 29.1 | 0.9 | 0 | 0 |
| 2024-01-01 22:00:00 | 2.5 | 25 | 1.1 | 29.1 | 0.9 | 0 | 0 |
| 2024-01-01 23:00:00 | 0 | 24 | 0 | 29.1 | 0.9 | 2.1 | 0 |
| 2024-01-02 00:00:00 | 0 | 24 | 0 | 29.1 | 30 | 0 | 0 |
求助点
单天逻辑没问题,但分块处理时,上一块结束时的电池容量Cap无法正确传递到下一块,导致后续日期的计算全部错误。需要修正分块遍历的逻辑,保证跨块的状态(比如剩余容量)能正确延续。
内容的提问来源于stack exchange,提问作者saguero
相关产品推荐
相关产品推荐

