如何用同一用户后续日期的同列数据填充Pandas DataFrame中的Null值
解决方案:按用户分组后向后填充并提取首行
看起来你想要的是按用户分组,用该用户后续日期的非空数据填充之前的Null值,最后每个用户保留一行最终的填充结果。这里可以用Pandas的groupby结合bfill()(向后填充)来实现,具体步骤如下:
步骤分解
- 首先确保数据按
user和date升序排列(注意要把排序后的结果赋值给新变量,或者用inplace=True修改原DataFrame) - 按
user分组,对需要填充的列(test1、test2、test3)使用bfill(),这样每个组内前面的Null会被后续的非空值覆盖 - 最后提取每个分组的第一行,就是我们要的最终结果
完整代码
import pandas as pd import numpy as np # 构建原始数据 array = {'user': ['Trevor', 'John', 'Trevor', 'John', 'Trevor', 'Trevor', 'John'], 'date': ['2020-10-11 08:00:00', '2020-10-15 08:00:00', '2020-10-17 08:00:00', '2020-10-19 08:00:00', '2020-10-10 08:00:00' , '2020-11-11 12:34:00', '2020-11-16 09:12:00'], 'test1': [5,np.nan,np.nan,np.nan,np.nan,8,4], 'test2': [np.nan,8,3,np.nan,1,8,6], 'test3': [np.nan,np.nan,3,5,np.nan,8,np.nan]} df = pd.DataFrame(array) # 1. 按user和date升序排序,注意要赋值保存结果 df_sorted = df.sort_values(by=['user', 'date'], ascending=True) # 2. 分组后向后填充,然后取每个组的第一行 result = df_sorted.groupby('user').apply(lambda x: x.bfill().head(1)).reset_index(drop=True) # 3. 去掉date列,和期望输出格式匹配 result = result.drop(columns=['date']) print(result)
输出结果
user test1 test2 test3 0 John 4.0 8.0 5.0 1 Trevor 5.0 1.0 3.0
关键说明
bfill():全称backward fill,会用当前位置之后的第一个非空值来填充当前的Null,完美匹配你用后续日期数据填充的需求groupby('user').apply(...):确保每个用户的数据单独处理,不会出现跨用户填充的错误head(1):填充完成后,每个用户的第一行已经包含了所有被后续有效值填充后的结果,所以只需要保留这一行即可
内容的提问来源于stack exchange,提问作者gtomer
相关产品推荐
相关产品推荐

