Pandas - 将列中的NaN替换为特定组的平均值

4

我正在处理以下类似的数据。数据帧按照日期排序:

category  value  Date
0         1      24/5/2019     
1         NaN    24/5/2019         
1         1      26/5/2019       
2         2      1/6/2019      
1         2      23/7/2019       
2         NaN    18/8/2019         
2         3      20/8/2019       
7         3      1/9/2019 
1         NaN    12/9/2019       
2         NaN      13/9/2019       

我希望能够用前一个特定类别的平均值来替换“NaN”值。
在pandas中,最好的方法是什么?
我考虑了一些方法:
1)这个小段落:
   df['mean' = df.groupby('category')['time'].apply(lambda x: x.shift().expanding().mean()))

来源

这个可以让我正确进入,但是在另一列中,并且它不会替换NaN。

2)这个小节用列的平均值替换NaN:

df = df.groupby(df.columns, axis = 1).transform(lambda x: x.fillna(x.mean()))

来源2

这两个选项都不完全符合我的需求。如果有人能指导我,我将非常感激!


你说的“特定类别的先前平均值”是什么意思?因为该类别会重复。 - Erfan
我的意思是,对于每个NaN值,查看相应的类别,在所有先前日期中找到该类别的平均值,然后用这个计算出的平均值替换NaN。 - Convex Leopard
df['value']=df['value'].fillna(df.groupby('category')['value'].transform(lambda x: x.shift().expanding().mean())) 的翻译是什么? - ansev
2个回答

4

您可以使用 shift + expanding + mean 中的新系列替换 value,因为第一个 1 组的值没有被替换,原因是没有前面的 NaN 值:

df['Date'] = pd.to_datetime(df['Date'])
s = df.groupby('category')['value'].apply(lambda x: x.shift().expanding().mean())
df['value'] = df['value'].fillna(s)
print (df)
   category  value       Date
0         0    1.0 2019-05-24
1         1    NaN 2019-05-24
2         1    1.0 2019-05-26
3         2    2.0 2019-01-06
4         1    2.0 2019-07-23
5         2    2.0 2019-08-18
6         2    3.0 2019-08-20
7         7    3.0 2019-01-09
8         1    1.5 2019-12-09
9         2    2.5 2019-09-13

谢谢,这是一些很棒的Python技巧。帮助我学习了一些新方法。 - Convex Leopard

2
你可以使用pandas.Series.fillna来替换NaN值:
df['value']=df['value'].fillna(df.groupby('category')['value'].transform(lambda x: x.shift().expanding().mean()))
print(df)

   category  value       Date
0         0    1.0  24/5/2019
1         1    NaN  24/5/2019
2         1    1.0  26/5/2019
3         2    2.0   1/6/2019
4         1    2.0  23/7/2019
5         2    2.0  18/8/2019
6         2    3.0  20/8/2019
7         7    3.0   1/9/2019
8         1    1.5  12/9/2019
9         2    2.5  13/9/2019

谢谢,这是一个很好的处理方式,我在这里学到了新东西! - Convex Leopard
1
你会感激如果你给@ConvexLeopard投正面票。 - ansev
当然,我已经点赞了(抱歉之前不知道可以点赞)。感谢您的帮助! - Convex Leopard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接