有条件地在Pandas数据框中填充空白值

时间:2018-10-12 14:45:47

标签: python pandas dataframe pandas-groupby series

我有一个数据场,如下所示(有更多列被删除):

    memberID    shipping_country    
    264991      
    264991       Canada
    100          USA    
    5000         
    5000         UK

我试图用每个用户的运送国家/地区的现有值填充空白单元格:

    memberID    shipping_country    
    264991       Canada
    264991       Canada
    100          USA    
    5000         UK
    5000         UK

但是,我不确定在大规模数据集上执行此操作最有效的方法是什么。也许是使用矢量分组方式?

3 个答案:

答案 0 :(得分:5)

您可以使用GroupBy + ffill / bfill

def filler(x):
    return x.ffill().bfill()

res = df.groupby('memberID')['shipping_country'].apply(filler)

自定义功能是必需的,因为顺序ffillbfill没有组合的熊猫方法。

这也满足了特定NaN的所有值均为memberID的情况;在这种情况下,它们将保留为NaN

答案 1 :(得分:2)

对于以下示例数据帧(我在memberID列中添加了一个''组,该组仅包含shipping_country

   memberID shipping_country
0    264991                 
1    264991           Canada
2       100              USA
3      5000                 
4      5000               UK
5        54                 

这应该对您有用,并且如果memberID组在''中仅包含空字符串值(shipping_country),则这些行为将保留在输出{ {1}}:

df

收益:

df['shipping_country'] = df.replace('',np.nan).groupby('memberID')['shipping_country'].transform('first').fillna('')

如果您想在输出 memberID shipping_country 0 264991 Canada 1 264991 Canada 2 100 USA 3 5000 UK 4 5000 UK 5 54 中将空字符串''保留为NaN,则只需删除df,然后保留:

fillna('')

答案 2 :(得分:1)

您可以使用链接的groupby,其中一个使用正向填充,另一个使用回填:

# replace blank values with `NaN` first:
df['shipping_country'].replace('',pd.np.nan,inplace=True)

df.iloc[::-1].groupby('memberID').ffill().groupby('memberID').bfill()

   memberID shipping_country
0    264991           Canada
1    264991           Canada
2       100              USA
3      5000               UK
4      5000               UK

此方法还将允许将由所有NaN组成的组保留为NaN

>>> df
   memberID shipping_country
0    264991                 
1    264991           Canada
2       100              USA
3      5000                 
4      5000               UK
5         1                 
6         1                 

df['shipping_country'].replace('',pd.np.nan,inplace=True)

df.iloc[::-1].groupby('memberID').ffill().groupby('memberID').bfill()

   memberID shipping_country
0    264991           Canada
1    264991           Canada
2       100              USA
3      5000               UK
4      5000               UK
5         1              NaN
6         1              NaN