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

如何在Pandas DataFrame中按规则补全缺失季度行并设置status

解决Pandas DataFrame中仅插入连续未使用首个季度的'out'行需求

实现思路

要搞定“连续多个未使用季度只在第一个季度加'out'行”这个需求,核心思路是先列出所有文件和季度的完整组合,再筛选出连续缺失段的首个季度,最后将补充行与原数据合并即可。

具体代码实现

步骤1:生成所有文件-季度的完整组合

先提取原数据中的唯一文件名,和给定季度列表做全量配对,确保每个文件都对应所有季度:

import pandas as pd

# 原测试数据
df_test = pd.DataFrame(data=None, columns=['file', 'quarter', 'status'])
df_test.file = ['file_1', 'file_1', 'file_2', 'file_2', 'file_3']
df_test.quarter = ['2022q4', '2023q2', '2022q3', '2022q4', '2023q1']
df_test.status = ['in', 'in', 'in', 'in', 'in']

# 固定季度列表
quarters = ['2022q3', '2022q4', '2023q1', '2023q2']

# 生成全量的文件-季度组合
all_files = df_test['file'].unique()
full_df = pd.MultiIndex.from_product([all_files, quarters], names=['file', 'quarter']).to_frame(index=False)

步骤2:合并原数据,标记缺失行

将全量组合与原数据左连接,找出原数据中没有记录的季度(即需要补充的行):

merged_df = pd.merge(full_df, df_test, on=['file', 'quarter'], how='left')
# 给缺失行打标记
merged_df['is_missing'] = merged_df['status'].isna()

步骤3:分组筛选连续缺失的首个季度

按文件分组处理,先按季度排序,再只保留连续缺失段的第一行:

def filter_first_missing(group):
    # 按季度排序(确保是时间顺序,这里quarters本身已排好序)
    group = group.sort_values('quarter')
    # 标记连续缺失的起始行
    group['is_first_missing'] = False
    # 第一行如果是缺失的,直接标记
    if group.iloc[0]['is_missing']:
        group.iloc[0, group.columns.get_loc('is_first_missing')] = True
    # 从第二行开始,判断当前行缺失且上一行不缺失的,就是连续缺失的起点
    for i in range(1, len(group)):
        if group.iloc[i]['is_missing'] and not group.iloc[i-1]['is_missing']:
            group.iloc[i, group.columns.get_loc('is_first_missing')] = True
    # 保留原有的'in'行,以及标记好的首个缺失行
    return group[(~group['is_missing']) | group['is_first_missing']]

# 分组处理每个文件
result_df = merged_df.groupby('file').apply(filter_first_missing).reset_index(drop=True)

步骤4:填充状态并整理结果

将筛选出的缺失行状态填充为'out',删除辅助列后排序:

# 填充缺失的状态为'out'
result_df['status'] = result_df['status'].fillna('out')
# 删除辅助列
result_df = result_df.drop(['is_missing', 'is_first_missing'], axis=1)
# 按文件和季度排序,匹配期望输出
result_df = result_df.sort_values(['file', 'quarter']).reset_index(drop=True)

print(result_df)

最终输出

运行代码后得到的结果与期望一致:

file quarter status
0  file_1  2022q4     in
1  file_1  2023q1    out
2  file_1  2023q2     in
3  file_2  2022q3     in
4  file_2  2022q4     in
5  file_2  2023q1    out
6  file_3  2023q1     in
7  file_3  2023q2    out

性能优化提示

如果处理的是大型DataFrame,循环效率较低,推荐用向量化写法替代循环,速度提升明显:

def filter_first_missing_vectorized(group):
    group = group.sort_values('quarter')
    # 用shift()判断:当前行缺失,且前一行不缺失(前一行不存在则用False填充)
    group['is_first_missing'] = group['is_missing'] & ~group['is_missing'].shift(fill_value=False)
    return group[(~group['is_missing']) | group['is_first_missing']]

替换上述filter_first_missing函数即可,逻辑完全一致,处理大数据集时更高效。


内容的提问来源于stack exchange,提问作者Marcus K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:43:14