pandas:填充组中的缺失值

pandas: Filling missing values within a group

提问人:Marius 提问时间:8/16/2013 更新时间:3/3/2018 访问量:11728

问:

我有一些来自实验的数据,在每个试验中,有一些单独的值,用 包围,我想填写到整个试验中:NA

df = pd.DataFrame({'trial': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], 
    'cs_name': [np.nan, 'A1', np.nan, np.nan, np.nan, np.nan, 'B2', 
                np.nan, 'A1', np.nan, np.nan, np.nan]})
Out[177]: 
   cs_name  trial
0      NaN      1
1       A1      1
2      NaN      1
3      NaN      1
4      NaN      2
5      NaN      2
6       B2      2
7      NaN      2
8       A1      3
9      NaN      3
10     NaN      3
11     NaN      3

我能够通过使用 和 在整个试验中填充这些值,但我想知道是否有更好的方法来实现这一目标。bfill()ffill()

df['cs_name'] = df.groupby('trial')['cs_name'].ffill()
df['cs_name'] = df.groupby('trial')['cs_name'].bfill()

预期输出:

   cs_name  trial
0       A1      1
1       A1      1
2       A1      1
3       A1      1
4       B2      2
5       B2      2
6       B2      2
7       B2      2
8       A1      3
9       A1      3
10      A1      3
11      A1      3
Python 熊猫

评论


答:

15赞 Andy Hayden 8/16/2013 #1

另一种方法是使用 first_valid_index转换

In [11]: g = df.groupby('trial')

In [12]: g['cs_name'].transform(lambda s: s.loc[s.first_valid_index()])
Out[12]: 
0     A1
1     A1
2     A1
3     A1
4     B2
5     B2
6     B2
7     B2
8     A1
9     A1
10    A1
11    A1
Name: cs_name, dtype: object

这应该比使用 ffill 后跟 bfill 更有效......

并使用它来更改列:cs_name

df['cs_name'] = g['cs_name'].transform(lambda s: s.loc[s.first_valid_index()])

注意:我认为有一个方法来获取熊猫中的第一个非空对象会很好,在 numpy 中它是一个开放请求,我认为目前没有方法(我可能是错的!...

6赞 Federico De Cillia 11/22/2017 #2

如果要避免某些组仅包含 NaN 时出现的错误,您可以执行以下操作(请注意,我更改了 df,因此具有 trial=1 的组只有 Nan):

df = pd.DataFrame({'trial': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,1,1], 
'cs_name': [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 'B2', np.nan, 
'A3', np.nan, np.nan, np.nan, np.nan,np.nan]})

g = data.groupby('trial')

g['cs_name'].transform(lambda s: 'No values to aggregate' if 
    pd.isnull(s).all() == True else s.loc[s.first_valid_index()])

df['cs_name'] = g['cs_name'].transform(lambda s: 'No values to aggregate' if 
    pd.isnull(s).all() == True else s.loc[s.first_valid_index()])`

这样,当程序找到特定组的所有 NaN 时,您可以输入“No Values to aggregate”(或您想要的任何值),而不是错误。

希望这对:)有所帮助

费德里科