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

如何用Pandas更优雅地计算DataFrame中各电流阶的平均电压

用Pandas Groupby优雅处理分阶电流的平均电压计算

嘿,这个需求用Pandas的groupby系列操作完全能替代循环,实现更简洁高效的代码!我来一步步给你拆解方案~

核心思路

你的需求本质是识别连续的电流阶段,然后剔除每个阶段的前N个不稳定数据,最后分组计算平均电压。用groupby可以避免手动循环,利用Pandas的向量化操作提升效率和可读性。

步骤1:准备示例数据(模拟你的实验场景)

先模拟一份和你数据匹配的样例,方便演示:

import pandas as pd
import numpy as np

np.random.seed(42)  # 固定随机种子,结果可复现
time = np.arange(0, 30, 1)
# 模拟3个电流阶,每个阶内有小幅度波动
current = np.concatenate([
    np.random.normal(1, 0.05, 10),   # 第一阶:~1A
    np.random.normal(2, 0.05, 10),   # 第二阶:~2A
    np.random.normal(1.5, 0.05, 10)  # 第三阶:~1.5A
])
# 模拟电压:每个阶切换后前3个值不稳定,后续趋于稳定
voltage = np.concatenate([
    np.random.normal(3, 0.5, 3) + np.linspace(0, 1, 3),  # 前3个不稳定
    np.random.normal(3, 0.1, 7),
    np.random.normal(5, 0.5, 3) + np.linspace(0, -1, 3),
    np.random.normal(5, 0.1, 7),
    np.random.normal(4, 0.5, 3) + np.linspace(0, 0.8, 3),
    np.random.normal(4, 0.1, 7)
])

df = pd.DataFrame({
    '时间(s)': time,
    '电流([A])': current,
    '电压([V])': voltage
})

步骤2:生成电流阶的分组ID

因为电流阶内有小波动,不能直接用电流值分组。我们通过判断相邻电流的变化幅度来识别阶跃:

# 设置电流阶跃阈值(根据你的实际数据调整,比如0.2A)
current_step_threshold = 0.2
# 生成分组ID:当相邻电流差的绝对值超过阈值时,分组ID+1
df['电流阶ID'] = (df['电流([A])'].diff().abs() > current_step_threshold).cumsum()

这样同一个电流阶的所有数据会被分到同一个电流阶ID下。

步骤3:剔除不稳定数据并计算平均电压

这里有两种高效的实现方式,推荐第二种(更适合大数据量场景):

方式1:用groupby.apply过滤后求均值

drop_n = 3  # 每个阶要剔除的前N个不稳定数据

# 分组后对每个组取第drop_n行之后的数据,再求电压均值
result = df.groupby('电流阶ID').apply(
    lambda group: group.iloc[drop_n:]['电压([V])'].mean()
).reset_index(name='平均电压([V])')

# 可选:添加每个电流阶的平均电流,方便查看
result['平均电流([A])'] = df.groupby('电流阶ID')['电流([A])'].mean().values

方式2:用cumcount标记组内行号,过滤后分组(更高效)

drop_n = 3

# 标记每个组内的行号(从0开始)
df['组内行号'] = df.groupby('电流阶ID').cumcount()
# 过滤掉每个组的前drop_n行
filtered_df = df[df['组内行号'] >= drop_n]
# 分组计算平均电流和电压
result = filtered_df.groupby('电流阶ID').agg(
    平均电流([A])=('电流([A])', 'mean'),
    平均电压([V])=('电压([V])', 'mean')
).reset_index()

输出结果示例

运行后得到的result大概是这样:

电流阶ID  平均电流([A])  平均电压([V])
0       0    1.004573    3.026412
1       1    2.005153    5.010887
2       2    1.498658    4.002345

额外优化:如果电流阶是固定值(可通过取整区分)

如果你的电流阶是明确的固定值(比如1A、2A,波动极小),可以直接对电流取整/保留小数来分组,代码更简洁:

df['电流阶'] = df['电流([A])'].round(1)  # 保留1位小数,把波动归为同一个阶
filtered_df = df.groupby('电流阶').apply(lambda x: x.iloc[drop_n:]).reset_index(drop=True)
result = filtered_df.groupby('电流阶').agg(
    平均电压([V])=('电压([V])', 'mean'),
    有效样本数=('电压([V])', 'count')
)

对比循环实现的优势

  • 代码更简洁,可读性更强,不需要手动处理循环边界和分组判断
  • 利用Pandas的向量化操作,大数据量下效率远高于循环
  • 更容易扩展(比如要加其他统计量,直接在agg里添加即可)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:00:50