python pandas 比较列并添加不同列的列表

python pandas compare columns and add list of columns that differ

我想比较数据框中的多个列并添加一个新列,告诉我每行哪些列不同。

例如,对于这个数据框,我想将 a1 与 a2 以及 b1 与 b2 进行比较:

   a1  b1  a2  b2
0   1   2   1   2
1   1   2   1   3
2   1   2   3   4

输出应该是这样的:

   a1  b1  a2  b2  diff
0   1   2   1   2  
1   1   2   1   3  'b1-b2'
2   1   2   3   4  'a1-a2,b1-b2'

这是我目前尝试过的方法:

import numpy as np
import pandas as pd
data = [{'a1': 1, 'b1': 2, 'a2':1, 'b2':2},
        {'a1':1, 'b1': 2, 'a2': 1, 'b2':3},
        {'a1':1, 'b1': 2, 'a2':3 , 'b2':4}]
df = pd.DataFrame(data)

compare = [('a1','a2'),('b1','b2')]
comp_result = np.array([(df[x[0]] != df[x[1]]) for x in compare])

comp_result 是每个比较的 True/False 值列表列表,但我不确定如何使用它来创建“差异”列。

您可以创建一个函数 compare_rows 获取数据帧的每一行并使用 compare 循环遍历每个所需的比较。使用列表理解,只保留每一行的不同列,并使用 str.join 以所需格式格式化输出。然后,您可以使用 .apply DataFrame 方法将函数应用于每一行。

import numpy as np
import pandas as pd
data = [{'a1': 1, 'b1': 2, 'a2':1, 'b2':2},
        {'a1':1, 'b1': 2, 'a2': 1, 'b2':3},
        {'a1':1, 'b1': 2, 'a2':3 , 'b2':4}]
df = pd.DataFrame(data)
compare = [('a1','a2'),('b1','b2')]

def compare_rows(row):
    differences = ['-'.join(comp)
                   for comp in compare
                   if row[comp[0]] != row[comp[1]]]
    return ','.join(differences)

df['diff'] = df.apply(compare_rows, axis=1)

快速 one-liner 无循环:

col_groups = [c.columns for _, c in df.groupby(df.columns.str[0], axis=1)]

df['diff'] = pd.Series(np.sum([(df[l] != df[r]).map({True: f'{l}-{r}',False:''}) + ',' for l, r in col_groups], axis=0)).str.strip(',')

输出:

>>> df
   a1  b1  a2  b2         diff
0   1   2   1   2             
1   1   2   1   3        b1-b2
2   1   2   3   4  a1-a2,b1-b2