【问题标题】:Pandas dataframe merging rows to remove NaNPandas 数据框合并行以删除 NaN
【发布时间】:2018-03-01 00:44:29
【问题描述】:

我有一个带有一些 NaN 的数据框:

hostname period Teff
51 Peg  4.2293  5773
51 Peg  4.231   NaN
51 Peg  4.23077 NaN
55 Cnc  44.3787 NaN
55 Cnc  44.373  NaN
55 Cnc  44.4175 NaN
55 Cnc  NaN 5234
61 Vir  NaN 5577
61 Vir  38.021  NaN
61 Vir  123.01  NaN

具有相同“主机名”的行都引用同一个对象,但正如您所见,一些条目在不同的列下都有 NaN。我想合并同一主机名下的所有行,以便在每列中保留第一个有限值(如果所有值都是 NaN,则删除该行)。所以结果应该是这样的:

hostname period Teff
51 Peg  4.2293  5773
55 Cnc  44.3787 5234
61 Vir  38.021  5577

你会怎么做呢?

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    使用groupby.first;它需要first non NA value:

    df.groupby('hostname')[['period', 'Teff']].first().reset_index()
    #  hostname   period  Teff
    #0      Cnc  44.3787  5234
    #1      Peg   4.2293  5773
    #2      Vir  38.0210  5577
    

    或者使用自定义聚合函数手动执行此操作:

    df.groupby('hostname')[['period', 'Teff']].agg(lambda x: x.dropna().iat[0]).reset_index()
    

    这要求每个组至少有一个非 NA 值。

    编写自己的函数来处理边缘情况:

    def first_(g):
        non_na = g.dropna()
        return non_na.iat[0] if len(non_na) > 0 else pd.np.nan
    
    df.groupby('hostname')[['period', 'Teff']].agg(first_).reset_index()
    
    #  hostname   period  Teff
    #0      Cnc  44.3787  5234
    #1      Peg   4.2293  5773
    #2      Vir  38.0210  5577
    

    【讨论】:

    • 您的两个解决方案都运行良好,除了它们还删除了所有其他列(如果我的数据框除了此处命名的这三个之外还有其他列)。
    • 如果你想从所有列中取第一个值,你应该能够简单地做df.groupby('hostname').first().reset_index()而不选择列。
    • 我明白了。这就是我需要它做的事情,而且简短而简单。谢谢!
    【解决方案2】:

    这是你需要的吗?

    pd.concat([ df1.apply(lambda x: sorted(x, key=pd.isnull)) for _, df1 in df.groupby('hostname')]).dropna()
    Out[343]: 
       hostname   period    Teff
    55      Cnc  44.3787  5234.0
    51      Peg   4.2293  5773.0
    61      Vir  38.0210  5577.0
    

    【讨论】:

    • 谢谢。这似乎与一个小的修改完美地工作,只在选定的列中删除 NaN:pd.concat([ df1.apply(lambda x: sorted(x, key=pd.isnull)) for _, df1 in df.groupby('hostname')]).dropna(subset=['period','Teff'])
    • @mcglashan aha , :-) 很高兴它有帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2018-02-24
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    相关资源
    最近更新 更多