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

如何为DataFrame按ID统计满足指定条件的观测行数

问题

我有一个包含多个变量的DataFrame,每个受试者(ID)对应多条观测行。需要为每个ID创建新变量,统计满足以下条件的观测行数:

  • AVG_STOCK_DEN > 100
  • DIM(观测天数)介于-14与-1之间

我尝试了两种实现方式,但未达到预期效果,代码如下:
1)

for group in dfy_pcp.groupby('ID'):
    if (dfy_pcp['DIM'] >= -14) & (dfy_pcp['DIM'] <= -1) & (dfy_pcp['avg_stock_den'] > 100):
        dfy_pcp['days_over_100_14'] = dfy_pcp['avg_stock_den'].count().any()
    else:
         dfy_pcp['days_over_100_14'] = 0
dfy_pcp['dfy_pcp_over_100_14'] = dfy_pcp[(dfy_pcp['DIM'] >= -14) & (dfy_pcp['DIM'] <= -1) & dfy_pcp['avg_stock_den'] > 100 ].groupby('ID')['avg_stock_den'].count().any()
解决方案

原代码问题说明

  • 第一种循环写法:遍历分组时未针对单个ID处理,直接操作整个DataFrame导致所有行被统一赋值;且count().any()逻辑错误,count()返回总数,any()会将非零值转为布尔值,无法得到符合条件的行数。
  • 第二种写法:count().any()会把分组统计结果转为单个布尔值(只要有分组有计数就返回True),赋值后整个列所有行都是同一个值,无法实现每个ID对应自身统计数的需求。

正确实现方法

方法1:使用transform(推荐)

# 标记符合条件的行
dfy_pcp['is_valid'] = (dfy_pcp['DIM'].between(-14, -1)) & (dfy_pcp['avg_stock_den'] > 100)

# 按ID分组统计符合条件的行数,将结果映射到每一行
dfy_pcp['days_over_100_14'] = dfy_pcp.groupby('ID')['is_valid'].transform('sum')

说明:between(-14, -1)等价于DIM >= -14 且 DIM <= -1;sum()会将布尔值True(1)和False(0)求和,得到每个ID符合条件的行数;transform保证每个ID的所有行都能获取对应的统计值。

方法2:先统计再合并

# 筛选符合条件的行,按ID统计行数
count_df = dfy_pcp[(dfy_pcp['DIM'].between(-14, -1)) & (dfy_pcp['avg_stock_den'] > 100)] \
           .groupby('ID')['avg_stock_den'].count().reset_index(name='days_over_100_14')

# 合并到原DataFrame,无符合条件的ID填充0
dfy_pcp = dfy_pcp.merge(count_df, on='ID', how='left').fillna({'days_over_100_14': 0})

说明:先筛选出符合条件的行并分组统计数量,再通过merge将统计结果合并回原DataFrame;how='left'确保所有原ID都保留,无符合条件的ID用fillna填充0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 21:15:06