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

分组数据指定区间Trapz积分:从起始到电流最小值的积分

问题描述

我有一个结构如下的DataFrame:

Device TimeSec Current
1      0.1     0.02
1      0.25    0.05
1      0.32    0.07
1      0.45    0.01
1      0.67    0.05
1      1.01    0.08
1      1.12    0.11
1      1.32    0.15
2      0.11    0.04
2      0.22    0.06
2      0.28    0.07
2      0.35    0.02
2      0.41    0.05
2      0.51    0.08
2      0.61    0.12
....

我的需求是:

  • 每个设备的数据组中存在一个电流最小值;
  • 按Device对DataFrame进行分组,并执行trapz积分;
  • 积分区间为每个设备数据的TimeSec起始点到Current最小值对应的位置。

我之前已经实现了对整个设备组的积分,代码如下:

DeviceGroup = df.groupby('Device')
Result = DeviceGroup.apply(lambda x: integrate.trapz(x.Current, x=x.TimeSec))

现在需要修改为从起始到Current最小值的区间积分,请问该如何实现?

解决方案

其实只需要在apply的lambda函数里做两步调整:先找到每组中Current最小值对应的行位置,再截取从开头到这个位置(包含该位置)的子数据进行积分就可以了。

具体实现代码

from scipy import integrate

# 分组后对每组数据执行自定义积分逻辑
result = df.groupby('Device').apply(lambda x:
    # 找到Current最小值对应的索引位置,截取数据后执行积分
    integrate.trapz(
        x.Current.iloc[:x.Current.idxmin() + 1],
        x=x.TimeSec.iloc[:x.Current.idxmin() + 1]
    )
)

代码解释

  1. x.Current.idxmin():这个方法会返回当前设备组中Current列最小值所在的组内相对索引(从0开始计数)。
  2. iloc[:x.Current.idxmin() + 1]:因为Python的切片是左闭右开规则,所以要加1才能包含最小值所在的那一行,这样就确保积分区间是从组内第一个数据点到电流最小值对应的点。
  3. 积分计算:把截取后的Current和TimeSec序列传入integrate.trapz,就能得到指定区间的积分结果。

特殊情况处理

如果同一个设备的Current列存在多个相同的最小值,idxmin()只会返回第一个出现的最小值位置。如果需要积分到最后一个最小值的位置,可以改成下面的逻辑:

from scipy import integrate

result = df.groupby('Device').apply(lambda x:
    # 找到所有等于最小值的行,取最后一行的索引
    min_rows = x[x.Current == x.Current.min()]
    last_min_loc = x.index.get_loc(min_rows.index[-1])
    # 基于位置截取数据并积分
    integrate.trapz(
        x.Current.iloc[:last_min_loc + 1],
        x=x.TimeSec.iloc[:last_min_loc + 1]
    )
)

这样就能确保积分区间覆盖到最后一个出现电流最小值的位置啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:03:03