基于日期的Pandas DataFrame指定代码滚动填充及首次出现查询
解决Pandas DataFrame的代码填充与首次记录查询需求
我来帮你搞定这个需求,分两步处理:先基于日期填充特定ID的缺失代码(仅A、B可延续),再提取各ID对应代码的首次出现记录。咱们直接上代码和解释~
第一步:准备示例数据
首先把你的示例数据补全并格式化,确保日期是datetime类型(保证排序逻辑正确):
import pandas as pd # 补全示例数据,加入缺失的Code值 d = { 'ID': [1, 2, 1, 2, 3, 1], 'date': ['2017-03-22', '2017-03-21', '2017-03-23', '2017-03-24', '2017-03-28', '2017-03-25'], 'Code': ['A', None, None, 'B', 'C', None] } df = pd.DataFrame(d) # 将date列转为datetime类型,避免字符串排序的问题 df['date'] = pd.to_datetime(df['date'])
第二步:填充缺失的Code(仅A、B可延续)
核心思路是按ID和日期排序后,仅当缺失值的前一条记录是A/B时才用前向填充,这样能避免非A/B的代码(比如示例中的C)被错误延续:
# 先按ID和日期排序,确保每个ID的记录是严格时间顺序 df_sorted = df.sort_values(['ID', 'date']).reset_index(drop=True) # 自定义分组填充函数 def fill_valid_codes(group): # 标记符合填充条件的行:当前Code为空,且上一行Code是A或B fill_mask = group['Code'].isna() & group['Code'].shift(1).isin(['A', 'B']) # 对符合条件的行做前向填充,其他行保持原样 group.loc[fill_mask, 'Code'] = group['Code'].ffill() return group # 按ID分组应用填充逻辑 df_filled = df_sorted.groupby('ID', group_keys=False).apply(fill_valid_codes) print("填充后的DataFrame:") print(df_filled)
执行后你会看到:ID=1的后续缺失值被填充为A,ID=2的初始缺失值因为前无有效代码保持为空,ID=3的C后面没有缺失值,完全符合需求。
第三步:提取各ID对应代码的首次出现记录
这里分两种常见场景,你可以按需选择:
场景1:每个ID下,每个Code的首次出现记录
# 先过滤掉仍为空的Code,再按ID+Code分组取最早的日期 first_code_occurrences = df_filled.dropna(subset=['Code']).groupby(['ID', 'Code'])['date'].min().reset_index() # 如果需要包含所有字段的完整记录,合并回原表即可 first_occurrences_full = df_filled.merge(first_code_occurrences, on=['ID', 'Code', 'date']) print("\n各ID对应代码的首次出现完整记录:") print(first_occurrences_full)
场景2:每个ID的第一条有效Code记录
如果你只需要每个ID第一次出现的有效Code记录,用这个更简洁:
id_first_valid_code = df_filled.dropna(subset=['Code']).groupby('ID').first().reset_index() print("\n每个ID的首次有效Code记录:") print(id_first_valid_code)
内容的提问来源于stack exchange,提问作者shbfy
相关产品推荐
相关产品推荐

