【问题标题】:Python: merge dataframes and keep all values in cells if not identicalPython:合并数据框并将所有值保留在单元格中(如果不相同)
【发布时间】:2023-01-10 10:16:12
【问题描述】:

所以我试图合并多个 excel 文件。每个文件将具有不同的尺寸。某些文件可能具有相同的列名,其中数据为 NULL、相同或不同。我编写的脚本合并了具有不同维度的多个文件,并删除了重复的列,最后一个值被删除到最后一个列单元格中。但是,我正在尝试连接值(如果不相等),以便用户可以手动浏览 excel 中的重复数据。

例子: 用户 1 在 df 表中的年龄 = 24,在 df1 中的年龄 = 27。我正在尝试在最终合并输出中获取该单元格中的两个值。

输入: 去向

user age team
1 24 x
2 56 y
3 32 z
df = pd.DataFrame({'user': ['1', '2', '3'],
                    'age': [24,56,32],
                    'team': [x,y,z]})

df1

user age name
1 27 Ronald
2 NaN Eugene
4 44 Jeff
5 61 Britney
df = pd.DataFrame({'user': ['1','2','4','5'],
                    'age': [27,NaN,44,61],
                    'name': ['Ronald','Eugene','Jeff','Britney']})

预期输出:

案例:

  1. 两个相同的值:保留一个

  2. 一个值是 NaN:保留非 NaN 值

  3. 两个不同的值:concat with delimiter 以便稍后查看。我会强调它。

    user age team name
    1 24 27
    2 56 y Eugene
    3 32 z NaN
    4 44 NaN Jeff
    5 61 NaN Britney

    这是我到目前为止所拥有的。用户将文件拖放到指定文件夹中,然后遍历所有 excel 文件。第一个循环将数据附加到 df 数据帧中,每个下一个循环都是合并。问题是,我只从最后一个循环中获取值(如果不为空)。

    df = pd.DataFrame()
    
    for excel_files in FILELIST:
        if excel_files.endswith(".xlsx"):
            df1 = pd.read_excel(FILEPATH_INPUT+excel_files, dtype=str)
            print(excel_files)
    
            if df.empty:
                df = df.append(df1)
            else:
                df = pd.merge(df,df1,on=UNIQUE_KEY,how=JOIN_METHOD,suffixes=('','_dupe'))
                df.drop([column for column in df.columns if '_dupe' in column],axis=1, inplace=True)
    

    这就是输出的样子

    user age team name
    1 27 x Ronald
    2 56 y Eugene
    3 32 z NaN
    4 44 NaN Jeff
    5 61 NaN Britney

    尝试遍历列然后连接。我可以在 df[new_col] 中看到组合值,但它无法更新 df 数据帧并且最终输出显示 NaN。

    df = pd.DataFrame()
    
    for excel_files in FILELIST:
        if excel_files.endswith(".xlsx"):
            df1 = pd.read_excel(FILEPATH_INPUT+excel_files, dtype=str)
            #df1.set_index('uid',inplace=True)
            print(excel_files)
            #print(df1)
            #print(df1.dtypes)
    
            if df.empty:
                df = df.append(df1)
            else:
                df = pd.merge(df,df1,on=UNIQUE_KEY,how=JOIN_METHOD,suffixes=('','_dupe'))
                #df.drop([column for column in df.columns if '_dupe' in column],axis=1, inplace=True)
    
                cols_to_remove = df.columns
                for column in cols_to_remove:
                    if "_dupe" in column:
                        new_col = str(column).replace('_dupe','')
    
                        df[new_col] = df[new_col].str.cat(df[column],sep='||')
                        print('New Values: ',df[new_col])
                        df.pop(column)
    

    任何帮助将不胜感激。谢谢拉夫

【问题讨论】:

    标签: python pandas dataframe merge concatenation


    【解决方案1】:

    我会 merge,然后在列上应用 groupby.agg

    merged = df.merge(df1, on='user', how='outer', suffixes=('', '_dupe'))
    
    out = (merged
     .groupby(merged.columns.str.replace('_dupe', ''), sort=False, axis=1)
     .agg('last')
    )
    

    输出:

      user   age  team     name
    0    1  27.0     x   Ronald
    1    2  56.0     y   Eugene
    2    3  32.0     z     None
    3    4  44.0  None     Jeff
    4    5  61.0  None  Britney
    

    替代输出:

    out = (merged
     .groupby(merged.columns.str.replace('_dupe', ''), sort=False, axis=1)
     .agg(lambda g: g.agg(lambda s: '|'.join(s.dropna().unique().astype(str)), axis=1))
    )
    

    输出:

      user        age team     name
    0    1  24.0|27.0    x   Ronald
    1    2       56.0    y   Eugene
    2    3       32.0    z         
    3    4       44.0          Jeff
    4    5       61.0       Britney
    

    【讨论】:

    • 太棒了,正是我所缺少的。非常感谢你的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 2019-08-30
    • 2012-11-04
    • 2015-08-05
    • 2021-04-11
    相关资源
    最近更新 更多