Pandas:按ID分组查找Type为Low的峰值并填充对应列
实现方案:按ID分组提取Type='Low'的Value峰值并填充对应列
示例输入数据
先构造示例输入的DataFrame:
import pandas as pd data = { 'ID': ['A', 'A', 'A', 'B', 'B', 'B'], 'Type': ['Low', 'High', 'Low', 'Low', 'High', 'Low'], 'Time': ['2024-01-01 10:00', '2024-01-01 11:00', '2024-01-01 12:00', '2024-01-01 09:00', '2024-01-01 10:00', '2024-01-01 11:00'], 'Value': [15, 30, 25, 10, 40, 18] } df = pd.DataFrame(data)
方法一:筛选聚合后合并回原表
- 先筛选
Type='Low'的行,按ID分组计算峰值及对应时间:
# 提取Type=Low的行,分组计算峰值和对应时间 peak_data = df[df['Type'] == 'Low'].groupby('ID').apply( lambda x: pd.Series({ 'Low_Peak_Value': x['Value'].max(), 'Peak_Time': x.loc[x['Value'].idxmax(), 'Time'] }) ).reset_index() # 合并回原DataFrame,确保所有行都填充对应ID的峰值信息 result = df.merge(peak_data, on='ID', how='left')
方法二:分组transform直接生成新列
这种方式无需额外合并,直接在原DataFrame上生成目标列,还能处理无Type='Low'行的ID(填充None):
def extract_peak(group): low_subgroup = group[group['Type'] == 'Low'] if low_subgroup.empty: return pd.Series([None, None], index=['Low_Peak_Value', 'Peak_Time']) max_val = low_subgroup['Value'].max() max_time = low_subgroup.loc[low_subgroup['Value'].idxmax(), 'Time'] return pd.Series([max_val, max_time], index=['Low_Peak_Value', 'Peak_Time']) # 按ID分组应用函数,生成新列 df[['Low_Peak_Value', 'Peak_Time']] = df.groupby('ID').apply(extract_peak).reset_index(drop=True)
示例输出结果
| ID | Type | Time | Value | Low_Peak_Value | Peak_Time |
|---|---|---|---|---|---|
| A | Low | 2024-01-01 10:00 | 15 | 25 | 2024-01-01 12:00 |
| A | High | 2024-01-01 11:00 | 30 | 25 | 2024-01-01 12:00 |
| A | Low | 2024-01-01 12:00 | 25 | 25 | 2024-01-01 12:00 |
| B | Low | 2024-01-01 09:00 | 10 | 18 | 2024-01-01 11:00 |
| B | High | 2024-01-01 10:00 | 40 | 18 | 2024-01-01 11:00 |
| B | Low | 2024-01-01 11:00 | 18 | 18 | 2024-01-01 11:00 |
注意事项
- 若同一ID的
Type='Low'行中存在多个相同峰值,idxmax()会取第一个出现的峰值对应的时间;若需要保留所有峰值时间,可将x.loc[x['Value'].idxmax(), 'Time']替换为x[x['Value'] == x['Value'].max()]['Time'].tolist()。 - 方法二中的空值处理逻辑可根据实际需求调整,比如填充默认值而非
None。
内容的提问来源于stack exchange,提问作者Gopinathan
相关产品推荐
相关产品推荐

