【问题标题】:Remove the identical values, and leave only different去掉相同的值,只留下不同的
【发布时间】:2023-01-03 20:57:19
【问题描述】:

我想知道是否有更好的解决方案来保留不同的值(以便轻松捕获它们)并删除某些列下的相同值。

    merged = pd.merge(us_df, gb_df, how='outer', indicator=True)

    res = pd.merge(merged[merged['_merge'] == 'left_only'].drop('_merge', axis=1),
                   merged[merged['_merge'] == 'right_only'].drop('_merge', axis=1),
                   on=us_df.columns.tolist()[0:col_range],
                   how='outer',
                   suffixes=('_US', '_GB')).fillna(' ')

    cols = [col for col in res.columns.tolist() if '_US' in col or '_GB' in col]
    sorted_cols = [col for col in res.columns.tolist() if '_US' not in col and '_GB' not in col] + sorted(cols)

我得到这张桌子(资源):

Id ages_GB ages_US salary_GB salary_US
6 45 45 34 67
43 12 11 65 65

到目前为止,我使用了这个迭代:

    cols = [ages_US, salary_US, ages_GB, salary_GB]
    for i, row in res.iterrows():
        for us, gb in zip(cols[:len(cols) // 2], cols[len(cols) // 2:]):
            if row[us] == row[gb]:
                res.at[i, us] = res.at[i, gb] = ' '

得到结果(其中列下的相同值替换为“”(空格)):

Id ages_GB ages_US salary_GB salary_US
6 34 67
43 12 11

是否有另一种方法可以得到类似的结果?

【问题讨论】:

    标签: pandas dataframe html-table


    【解决方案1】:

    鉴于您的示例,我认为 loc 提供了一个更简单的解决方案,假设您想要比较两组列。

    我将首先重新创建一个可重现的数据集示例(我建议您在以后的问题中创建它,因为它更容易理解和回答您的问题:How to create a Minimal, Reproducible Example

    d = {
    'ages_GB': [45, 12],
    'ages_US': [45, 11],
    'salary_GB': [34, 65],
    'salary_US': [67, 65]
    }
    
    df = pd.DataFrame(data=d)
    print(df)
    

    初始数据框

       ages_GB  ages_US  salary_GB  salary_US
    0       45       45         34         67
    1       12       11         65         65
    

    我能想到的最简单的解决方案是使用loc将记录重新分配给""NaN,其中ages_GB == ages_USsalary_GB == salary_US

    df.loc[df.ages_GB == df.ages_US, ['ages_GB', 'ages_US']] = ["", ""]
    df.loc[df.salary_GB == df.salary_US, ['salary_GB', 'salary_US']] = ["", ""]
    

    输出

      ages_GB ages_US salary_GB salary_US
    0                        34        67
    1      12      11                    
    

    【讨论】:

      【解决方案2】:

      对于通用方法,您可以使用列前缀在axis=1groupby,并获取重复值以与mask一起使用:

      prefix = df.columns.str.extract('^([^_]+)', expand=False)
      # ['Id', 'ages', 'ages', 'salary', 'salary']
      
      m = df.groupby(prefix, axis=1).transform(lambda s: s.duplicated(keep=False))
      
      out = df.mask(m, '')
      

      输出:

         Id ages_GB ages_US salary_GB salary_US
      0   6                        34        67
      1  43      12      11                    
      

      中级m

            Id  ages_GB  ages_US  salary_GB  salary_US
      0  False     True     True      False      False
      1  False    False    False       True       True
      

      【讨论】:

        猜你喜欢
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 2017-01-24
        • 2020-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-25
        相关资源
        最近更新 更多