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

Python-Pandas:优化DataFrame逐行计算速度并解决SettingWithCopyWarning

储能计算器优化方案

一、先解决SettingWithCopy警告

  • 避免直接对DataFrame切片生成的视图赋值,比如不要用df_sub = total_profile[['col1', 'col2']]后修改df_sub,改用df_sub = total_profile[['col1', 'col2']].copy()创建独立副本。
  • 所有赋值操作统一使用.loc明确指定索引,比如把total_profile['battery_charge'][i] = x改为total_profile.loc[total_profile.index[i], 'battery_charge'] = x,确保操作的是原DataFrame的真实数据而非视图。

二、循环提速:用Numba加速逐行计算

由于计算依赖前一行的储能状态,属于有状态迭代计算,普通Python循环在大DataFrame上效率极低,用Numba的JIT编译可将循环速度提升几十倍,轻松实现耗时降低90%的目标。

步骤1:提取输入数组

将DataFrame中需要参与计算的列转换为numpy数组,Numba对numpy数组的处理效率远高于原生DataFrame:

import numba
import numpy as np
import pandas as pd

# 假设你的DataFrame包含以下核心列
solar = total_profile['solar_generation'].values
load = total_profile['load_demand'].values
max_capacity = total_profile['battery_capacity'].values  # 若容量固定,可直接设为标量
initial_charge = 0.0  # 初始储能电量

# 预先分配输出数组内存,避免动态扩容耗时
battery_charge = np.zeros_like(solar)
excess_solar = np.zeros_like(solar)

步骤2:编写Numba加速函数

@numba.jit(nopython=True)  # nopython模式是Numba最快的运行模式
def calculate_storage(solar, load, max_capacity, initial_charge):
    n = len(solar)
    charge = np.zeros(n)
    excess = np.zeros(n)
    current_charge = initial_charge
    
    for i in range(n):
        net = solar[i] - load[i]
        if net > 0:
            # 有多余太阳能,存入储能(受剩余容量限制)
            possible_charge = min(net, max_capacity[i] - current_charge)
            charge[i] = current_charge + possible_charge
            excess[i] = net - possible_charge
        else:
            # 无多余太阳能,维持或消耗储能(可根据实际逻辑调整)
            charge[i] = current_charge + net
            excess[i] = 0
        current_charge = charge[i]
    return charge, excess

步骤3:运行计算并回写DataFrame

# 执行加速计算
battery_charge, excess_solar = calculate_storage(solar, load, max_capacity, initial_charge)

# 用.loc回写结果,彻底规避警告
total_profile.loc[:, 'battery_charge'] = battery_charge
total_profile.loc[:, 'excess_solar'] = excess_solar

三、备选方案:用pandas expanding.apply(适合简单逻辑)

如果计算逻辑相对简单,也可以用expanding.apply结合状态变量实现,效率虽略低于Numba,但远快于普通循环:

def storage_step(state, row):
    current_charge, max_cap = state
    net = row['solar_generation'] - row['load_demand']
    if net > 0:
        add = min(net, max_cap - current_charge)
        new_charge = current_charge + add
        excess = net - add
    else:
        new_charge = current_charge + net
        excess = 0
    return new_charge, excess

# 初始化状态
initial_state = (0.0, total_profile['battery_capacity'].iloc[0])
# 逐行迭代计算
results = total_profile.expanding().apply(lambda x: storage_step(initial_state, x.iloc[-1]), axis=1)
# 拆分结果并回写DataFrame
total_profile[['battery_charge', 'excess_solar']] = pd.DataFrame(results.tolist(), index=total_profile.index)

关键注意事项

  • Numba的nopython=True模式要求函数内仅使用Numba支持的语法和对象,因此要避免在函数内操作pandas对象,统一用numpy数组。
  • 若储能有充放电效率、最低容量限制等额外逻辑,可直接在Numba函数内修改,不影响加速效果。
  • 所有DataFrame赋值操作坚持用.loc,彻底消除SettingWithCopy警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 20:35:23