如何在Pandas DataFrame同组内填充生成date_fill列?
解决Pandas按组填充非空日期值的问题
需求说明
需要为现有Pandas DataFrame生成date_fill列:当name列值相同时,将该组内date列的非空值填充至该组所有行的date_fill列。
输入DataFrame
name group date 0 a sdf NaN 1 a dss NaN 2 a fff 2022-10-23 3 b ggg NaN 4 b few NaN 5 b mjf NaN 6 c ggj NaN 7 c ojg NaN 8 c ert NaN 9 c dfg 2022-11-03
预期输出
name group date date_fill 0 a sdf NaN 2022-10-23 1 a dss NaN 2022-10-23 2 a fff 2022-10-23 2022-10-23 3 b ggg NaN NaN 4 b few NaN NaN 5 b mjf NaN NaN 6 c ggj NaN 2022-11-03 7 c ojg NaN 2022-11-03 8 c ert NaN 2022-11-03 9 c dfg 2022-11-03 2022-11-03
原代码问题分析
你尝试的逐行apply方法逻辑存在缺陷:
shift(-1)是对整个DataFrame的行进行移位,不是在name分组内操作,无法覆盖同组的所有行- 仅通过判断当前行与下一行的
name是否相同来赋值,逻辑范围太窄,无法处理组内多行的情况
正确实现方法
方法1:分组后用transform结合填充函数
利用groupby按name分组,再通过transform方法将组内的非空值填充到所有行:
import pandas as pd import numpy as np # 构造输入数据 df = pd.DataFrame({ 'name': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c'], 'group': ['sdf', 'dss', 'fff', 'ggg', 'few', 'mjf', 'ggj', 'ojg', 'ert', 'dfg'], 'date': [np.nan, np.nan, '2022-10-23', np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, '2022-11-03'] }) # 按name分组,用bfill()填充组内的NaN,生成date_fill列 df['date_fill'] = df.groupby('name')['date'].transform(lambda x: x.bfill())
groupby('name'):将数据按name列分组transform:确保返回结果与原DataFrame行数一致,保留原索引bfill():向后填充组内的NaN值,由于每组仅存在一个非空日期,该值会被填充到组内所有行
如果组内的非空值在开头,也可以用ffill()(向前填充),效果一致。
方法2:提取分组映射值后填充
先提取每个name对应的非空日期,再通过映射填充到原数据:
# 筛选出date非空的行,构建name到date的映射 date_mapping = df.dropna(subset=['date']).set_index('name')['date'] # 将映射值填充到date_fill列 df['date_fill'] = df['name'].map(date_mapping)
dropna(subset=['date']):筛选出date列非空的行set_index('name')['date']:创建以name为键、date为值的Seriesmap(date_mapping):将每个name对应的日期填充到date_fill列
这种方法更高效,尤其适合每组仅存在一个非空值的场景。
内容的提问来源于stack exchange,提问作者StephL
相关产品推荐
相关产品推荐

