代码之家  ›  专栏  ›  技术社区  ›  Michael Dorner Satyanarayana

如果无或nan,则合并pandas中的两行

  •  1
  • Michael Dorner Satyanarayana  · 技术社区  · 8 年前

    对于给定的数据帧 df

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

    我想 groupby 如果只有 None 或 nan 在分组行的列中,因此生成的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)
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   Bharath M Shetty    8 年前

    这可能是最慢的解决方案,您可以将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
  •  1
  •   BENY    8 年前

    groupby + first

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