Python中按客户-设备分组填充Closing Date至指定日期的实现方法
问题描述
现有一个按Customer-Equipment、Date、Closing_Date分组的pandas DataFrame,示例数据如下:
| Customer- Equipment | Date | Closing Date |
|---|---|---|
| Customer1 - Equipment A | 2023-01-01 | 2023-01-05 |
| Customer1 - Equipment A | 2023-01-02 | NaN |
| Customer1 - Equipment A | 2023-01-03 | NaN |
| Customer1 - Equipment A | 2023-01-04 | NaN |
| Customer1 - Equipment A | 2023-01-05 | NaN |
| Customer1 - Equipment A | 2023-01-06 | NaN |
| Customer2 - Equipment H | 2023-01-01 | 2023-01-02 |
| Customer2 - Equipment H | 2023-01-02 | NaN |
| Customer2 - Equipment H | 2023-01-03 | NaN |
需要填充Closing Date列的NaN值,规则为:
- 填充值为该组的
Closing Date非空值 - 仅填充到该行
Date等于该组Closing Date的行 - 超过该日期的行仍保留NaN
期望结果如下:
| Customer- Equipment | Date | Closing Date |
|---|---|---|
| Customer1 - Equipment A | 2023-01-01 | 2023-01-05 |
| Customer1 - Equipment A | 2023-01-02 | 2023-01-05 |
| Customer1 - Equipment A | 2023-01-03 | 2023-01-05 |
| Customer1 - Equipment A | 2023-01-04 | 2023-01-05 |
| Customer1 - Equipment A | 2023-01-05 | 2023-01-05 |
| Customer1 - Equipment A | 2023-01-06 | NaN |
| Customer2 - Equipment H | 2023-01-01 | 2023-01-02 |
| Customer2 - Equipment H | 2023-01-02 | 2023-01-02 |
| Customer2 - Equipment H | 2023-01-03 | NaN |
用户尝试的代码:
df['test'] = df.groupby('Customer-Equipment').apply( lambda x: x['Closing date'] if x['date'] <= x.at[row.index -1 ,'closing date'] else pd.NaT).fillna(method = 'ffill').reset_index(drop=True)
解决方案
实现思路
- 先将
Date和Closing Date转为datetime类型,避免字符串比较出错 - 按
Customer-Equipment分组,提取每组唯一的非空Closing Date值 - 对组内每行做判断:若
Date小于等于该组的Closing Date则填充对应值,否则保留NaN
完整代码
import pandas as pd # 转换日期列类型(如果原始数据是字符串格式) df['Date'] = pd.to_datetime(df['Date']) df['Closing Date'] = pd.to_datetime(df['Closing Date']) def fill_closing_date(group): # 获取该组的有效Closing Date(假设每组仅一个非空值) target_date = group['Closing Date'].dropna().iloc[0] # 按条件填充列 group['Closing Date'] = group.apply( lambda row: target_date if row['Date'] <= target_date else pd.NaT, axis=1 ) return group # 分组应用函数并重置结构 df = df.groupby('Customer-Equipment', group_keys=False).apply(fill_closing_date)
代码说明
- 类型转换:确保日期列是datetime格式,保证日期比较的准确性
- 分组处理:针对每个客户-设备组提取唯一的有效截止日期,适配示例数据的单值场景;若存在多值场景,可调整为取最新/最早值
- 条件填充:逐行判断日期是否在截止范围内,精准控制填充范围
- group_keys=False:避免分组后索引带上分组键,保持原数据结构不变
内容的提问来源于stack exchange,提问作者JLL
相关产品推荐
相关产品推荐

