【问题标题】:Merge two rows in pandas if None or nan如果 None 或 nan 合并 pandas 中的两行
【发布时间】:2018-06-25 07:50:12
【问题描述】:

对于给定的数据框df

df = pd.DataFrame({
    'id': [1, 2, 2], 
    'name': ['Peter', 'Max', None], 
    'age': [50.0, np.nan, 60.0]
})

如果分组行的列中只有一个None 或nan,我想groupby 并合并数据,以便生成的df 看起来像

        age     id  name
id              
1   0   50.0    1   Peter
2   1   60.0    2   Max

有没有比这个更好的解决方案:

def f(df):
    names = set(df['name']) - {None}
    if len(names) == 1:
        df['name'] = names.pop()
    else:
        print('Error: Names are not mergeable:', names)

    ages = {age for age in df['age'] if ~np.isnan(age)}
    if len(ages) == 1:
        df['age'] = ages.pop()
    else:
        print('Error: Ages are not mergeable:', ages)

    df = df.drop_duplicates()
    return df

df.groupby('id').apply(f)

【问题讨论】:

  • 如果您有两行以上的缺失值怎么办?

标签: python pandas nan pandas-groupby


【解决方案1】:

这可能是最慢的解决方案,您可以将 nan 排序到最后并将它们放入 groupby 即

df = pd.DataFrame({
    'id': [1, 2, 2,1,2], 
    'name': ['Peter', 'Max', None,'Daniel','Sign'], 
    'age': [50.0, np.nan, 60.0,40,30]
})
#    age  id    name
#0  50.0   1   Peter
#1   NaN   2     Max  
#2  60.0   2    None
#3  40.0   1  Daniel
#4  30.0   2    Sign

df.groupby('id').apply(lambda x: x.apply(sorted,key=pd.isnull).dropna()).reset_index(drop=True)

    age  id    name
0  50.0   1   Peter
1  40.0   1  Daniel
2  60.0   2     Max
3  30.0   2    Sign

【讨论】:

    【解决方案2】:

    groupby + first

    df.groupby('id').first()
    Out[877]: 
         age   name
    id             
    1   50.0  Peter
    2   60.0    Max
    

    【讨论】:

    • 感谢您的建议,但我认为它不能回答我的问题。它假设没有冲突,对吧?假设我们有另一行 [1, 'Daniel', 40.0] 并且它也不起作用,如果该组以 None 开头。
    猜你喜欢
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 2019-09-07
    • 2019-07-26
    • 2020-03-12
    • 1970-01-01
    相关资源
    最近更新 更多