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

如何在Pandas DataFrame中按日分块处理电池充放电数据

分块处理CSV时电池充放电/容量计算逻辑出错(单天逻辑已验证)

背景与需求

我有一份记录电池每小时放电量、温度的CSV文件,时间规则是每天13:00为分界点:

  • 前10小时(13:00 ~ 次日01:00):放电时段
  • 后14小时(次日01:00 ~ 当日13:00):充电时段

需要完成以下计算:

  1. 计算每日放电时段(前10h)Energy列的总和EnergySum,如果总和超过26就强制设为26
  2. 基于EnergySum计算电池当前容量Cap
  3. 添加Charged列:放电时段固定为0;充电时段根据当前Cap补充至满电,只记录实际需要的补电量,补满后后续充电时段的Charged设为0
  4. 添加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

预期输出示例

处理后的每条数据应包含新增列,示例如下:

DatetimeEnergyTemperatureElectricityEnergySumCapChargedConsumption
2024-01-01 13:00:003.2251.529.10.900
2024-01-01 22:00:002.5251.129.10.900
2024-01-01 23:00:00024029.10.92.10
2024-01-02 00:00:00024029.13000

求助点

单天逻辑没问题,但分块处理时,上一块结束时的电池容量Cap无法正确传递到下一块,导致后续日期的计算全部错误。需要修正分块遍历的逻辑,保证跨块的状态(比如剩余容量)能正确延续。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:06:17