【问题标题】:Remove group of empty or nan in pandas groupby删除 pandas groupby 中的空或 nan 组
【发布时间】:2020-04-01 08:27:31
【问题描述】:

在数据框中,某些行中有一些空 (NaN) 值 - 示例如下

s = pd.DataFrame([[39877380,158232151,20], [39877380,332086469,], [39877380,39877381,14], [39877380,39877383,8], [73516838,6439138,1], [73516838,6500551,], [735571896,203559638,], [735571896,282186552,], [736453090,6126187,], [673117474,12196071,], [673117474,12209800,], [673117474,618058747,6]], columns=['start','end','total'])

当我分组开始和结束列时

s.groupby(['start', 'end']).total.sum()

我得到的输出是

start      end
39877380   39877381    14.00
           39877383     8.00
           158232151   20.00
           332086469     nan
73516838   6439138      1.00
           6500551       nan
673117474  12196071      nan
           12209800      nan
           618058747    6.00
735571896  203559638     nan
           282186552     nan
736453090  6126187       nan

我想排除所有带有 end 的值都是“nan”的 start 组 - 预期输出 -

start      end
39877380   39877381    14.00
           39877383     8.00
           158232151   20.00
           332086469     nan
73516838   6439138      1.00
           6500551       nan
673117474  12196071      nan
           12209800      nan
           618058747    6.00

我尝试使用 dropna(),但它正在删除所有 nan 值而不是 nan 组。

我是 python 和 pandas 的新手。有人可以帮助我吗?谢谢

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    在较新的 pandas 版本中,如果使用 sum,则必须使用 min_count=1 作为缺失值:

    s1 = s.groupby(['start', 'end']).total.sum(min_count=1)
    #oldier pandas version solution
    #s1 = s.groupby(['start', 'end']).total.sum()
    

    如果Series.notnaGroupBy.transformGroupBy.any 在第一级至少有一个非缺失值,则可以过滤,过滤是boolean indexing

    s2 = s1[s1.notna().groupby(level=0).transform('any')]
    #oldier pandas version solution
    #s2 = s1[s1.notnull().groupby(level=0).transform('any')]
    print (s2)
    start      end      
    39877380   39877381     14.0
               39877383      8.0
               158232151    20.0
               332086469     NaN
    73516838   6439138       1.0
               6500551       NaN
    673117474  12196071      NaN
               12209800      NaN
               618058747     6.0
    Name: total, dtype: float64
    

    或者可以通过MultiIndex.get_level_values获取第一级索引值的唯一值并通过DataFrame.loc过滤:

    idx = s1.index.get_level_values(0)
    s2 = s1.loc[idx[s1.notna()].unique()]
    #oldier pandas version solution
    #s2 = s1.loc[idx[s1.notnull()].unique()]
    print (s2)
    start      end      
    39877380   39877381     14.0
               39877383      8.0
               158232151    20.0
               332086469     NaN
    73516838   6439138       1.0
               6500551       NaN
    673117474  12196071      NaN
               12209800      NaN
               618058747     6.0
    Name: total, dtype: float64
    

    【讨论】:

    • 我尝试了您建议的两种方法,但我无法执行s1[s1.notna().groupby(level=0).transform('any')] 步骤并收到错误AttributeError: 'DataFrame' object has no attribute 'notna'
    • @csvb - 仅适用于较旧的 pandas,仅将 notna() 更改为 notnull()
    • notnull() 替换notna() 无效。我仍然看到最后 3 行,但不是 nan 现在它们都是 0.00
    • @csvb - 所以使用s1 = s.groupby(['start', 'end']).total.sum(min_count=1) 而不是s1 = s.groupby(['start', 'end']).total.sum()
    • 我仍然无法获得预期的结果。我按照你提到的步骤进行。 @jezrael
    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多