如何在任意顺序中找到多个pandas数据帧中的一对列的交集?

Ash*_*osh 2 python dataframe python-3.x pandas

我有多个pandas数据帧,为了保持简单,让我说我有三个.

   >> df1=
       col1  col2
   id1  A     B  
   id2  C     D  
   id3  B     A  
   id4  E     F  


    >> df2=
       col1  col2
   id1  B     A  
   id2  D     C  
   id3  M     N  
   id4  F     E  

    >> df3=
       col1  col2
   id1  A     B  
   id2  D     C  
   id3  N     M  
   id4  E     F  
Run Code Online (Sandbox Code Playgroud)

需要的结果是:

    >> df=
       col1  col2
   id1  A     B
   id2  C     D
   id3  E     F
Run Code Online (Sandbox Code Playgroud)

因为对(A,B),(C,D),(E,F)出现在所有数据帧中,尽管它可以颠倒.

使用pandas merge时,只考虑列的传递方式.为了检查我的观察,我尝试了两个数据框的以下代码:

df1['reverse_1'] = (df1.col1+df1.col2).isin(df2.col1 + df2.col2)

df1['reverse_2'] = (df1.col1+df1.col2).isin(df2.col2 + df2.col1)
Run Code Online (Sandbox Code Playgroud)

我发现结果不同:

col1    col2    reverse_1   reverse_2
 a        b       False      True
 c        d       False      True
 b        a       True       False
 e        f       False      True
Run Code Online (Sandbox Code Playgroud)

因此,如果我从reverse_1和reverse_2列收集'True'值,我可以获得两个数据帧的交叉.即使我为两个数据帧执行此操作,我也不清楚如何继续处理更多数据帧(超过两个).我对此感到困惑.有什么建议?

jez*_*ael 5

您可以创建DataFrames 列表并在每行的列表理解排序中删除重复项:

dfs = [df1,df2,df3]

L = [pd.DataFrame(np.sort(x.values, axis=1), columns=x.columns).drop_duplicates() 
     for x in dfs]
print (L)
[  col1 col2
0    A    B
1    C    D
3    E    F,   col1 col2
0    A    B
1    C    D
2    M    N
3    E    F,   col1 col2
0    A    B
1    C    D
2    M    N
3    E    F]
Run Code Online (Sandbox Code Playgroud)

然后merge list of DataFrames按所有列(无参数on):

from functools import reduce
df = reduce(lambda left,right: pd.merge(left,right), L)
print (df)
  col1 col2
0    A    B
1    C    D
2    E    F
Run Code Online (Sandbox Code Playgroud)

@pygo的另一个解决方案:

创建indexfrozensets,不联合起来concatinner加盟,最后通过去除通过索引重复duplicated使用boolean indexing,并iloc为获得第2列:

df = pd.concat([x.set_index(x.apply(frozenset, axis=1)) for x in dfs], axis=1, join='inner')
df = df.iloc[~df.index.duplicated(), :2]
print (df)
       col1 col2
(B, A)    A    B
(C, D)    C    D
(F, E)    E    F
Run Code Online (Sandbox Code Playgroud)