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

按CODE和QUARTER分组获取PP<1连续时段起止日期及统计

问题描述

现有如下DataFrame:

DATE    CODE      QUARTER  PP
0        1964-01-01  100007    1964Q1  NaN
1        1964-01-02  100007    1964Q1  NaN
2        1964-01-03  100007    1964Q1  NaN
3        1964-01-04  100007    1964Q1  NaN
4        1964-01-05  100007    1964Q1  NaN
            ...     ...       ...  ...
10656619 2023-03-27  118004    2023Q1  0.0
10656620 2023-03-28  118004    2023Q1  0.0
10656621 2023-03-29  118004    2023Q1  0.0
10656622 2023-03-30  118004    2023Q1  0.0
10656623 2023-03-31  118004    2023Q1  0.0

[2647935 rows x 4 columns]

需求:按CODE和QUARTER分组,完成三个统计:

  • PP<1的最长连续天数
  • 该最长连续时段的起止日期
  • 每组内PP列的总NaN数量

已编写部分代码计算最长连续天数:

df['CONDITION']=(df['PP']<1)
#CALCULATE THE maximum value of consecutive days in which PP<1
max_values = (df.groupby(['CODE','QUARTER'])
       .apply(lambda g: (g['CONDITION'].ne(g['CONDITION'].shift()).cumsum() # Group continuous 
                         [g['CONDITION']]                                   # Keep True
                         .value_counts().max()))                            # Find max True
       .to_frame('MAX_CONSEC_VALUES').reset_index())

需要补充代码实现另外两个需求。

解决方案

可以通过扩展分组内的计算逻辑,一次性获取所有需要的统计项,具体代码如下:

步骤1:预处理日期列(确保为datetime类型)

如果DATE列当前是字符串格式,先转换为datetime:

df['DATE'] = pd.to_datetime(df['DATE'])

步骤2:扩展分组计算逻辑

替换原有的apply函数,在每个分组内同时计算最长连续段的起止日期、长度,以及NaN数量:

df['CONDITION'] = df['PP'] < 1

def process_group(g):
    # 生成连续段的分组键:CONDITION变化时,分组ID递增
    g['GROUP_ID'] = g['CONDITION'].ne(g['CONDITION'].shift()).cumsum()
    
    # 筛选出PP<1的连续段,计算每个段的起止日期和长度
    valid_segments = g[g['CONDITION']].groupby('GROUP_ID').agg(
        start_date=('DATE', 'min'),
        end_date=('DATE', 'max'),
        duration=('DATE', 'count')
    )
    
    # 获取最长连续段的信息,若无有效段则填充NaN/0
    if not valid_segments.empty:
        longest_segment = valid_segments[valid_segments['duration'] == valid_segments['duration'].max()].iloc[0]
        max_duration = longest_segment['duration']
        start_date = longest_segment['start_date']
        end_date = longest_segment['end_date']
    else:
        max_duration = 0
        start_date = pd.NaT
        end_date = pd.NaT
    
    # 统计当前分组的NaN数量
    nan_count = g['PP'].isna().sum()
    
    return pd.Series({
        'MAX_CONSEC_VALUES': max_duration,
        'START_DATE': start_date,
        'END_DATE': end_date,
        'TOTAL_NAN': nan_count
    })

# 分组计算并整理结果
result = df.groupby(['CODE', 'QUARTER']).apply(process_group).reset_index()

代码说明

  • GROUP_ID列用于标识连续的符合条件(PP<1)的时段,每次CONDITION值变化时,ID自动递增
  • 对每个有效连续段,通过agg计算起止日期和持续天数
  • 筛选出持续天数最大的段,若没有有效段(比如分组内全是PP>=1或全NaN),则起止日期设为pd.NaT,持续天数为0
  • 直接用isna().sum()统计分组内PP列的NaN总数

最终的resultDataFrame会包含CODE、QUARTER、MAX_CONSEC_VALUES、START_DATE、END_DATE、TOTAL_NAN这几列,满足所有需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:02:48