仅外连接 python 熊猫

Leg*_*ack 3 python outer-join dataframe pandas

我有两个 DataFrame 具有相同的列名,其中包含一些匹配数据和一些唯一数据。

我想排除中间部分,只保存两个 DataFrame 的独特之处。

我将如何连接或合并或加入这两个数据帧来做到这一点?

例如在这张图片中,我不想要这张图片的中间,我想要两边而不是中间:

在此处输入图片说明

这是我现在的代码:

def query_to_df(query):
    ...
    df_a = pd.DataFrame(data_a)
    df_b = pd.DataFrame(data_b)
    outer_results = pd.concat([df_a, df_b], axis=1, join='outer')
    return df
Run Code Online (Sandbox Code Playgroud)

让我举个例子说明我需要什么:

df_a = 
col_a  col_b  col_c
   a1     b1     c1
   a2     b2     c2

df_b = 
col_a  col_b  col_c
   a2     b2     c2
   a3     b3     c3

# they only share the 2nd row:    a2     b2     c2 
# so the outer result should be:
col_a  col_b  col_c  col_a  col_b  col_c
   a1     b1     c1     NA     NA     NA
   NA     NA     NA     a3     b3     c3
Run Code Online (Sandbox Code Playgroud)

或者我也会对 2 个数据框感到满意

result_1 =
col_a  col_b  col_c
   a1     b1     c1

result_2 =
col_a  col_b  col_c
   a3     b3     c3
Run Code Online (Sandbox Code Playgroud)

最后,您会注意到a2 b2 c2 因为所有列都匹配而被排除 - 我如何指定我要基于所有列加入,而不仅仅是 1?如果df_a有的话,a2 foo c2我也会希望那一行result_1也在。

jez*_*ael 5

先使用mergewithindicator参数和outerjoin ,然后按queryor过滤boolean indexing

df = df_a.merge(df_b, how='outer', indicator=True)
print (df)
  col_a col_b col_c      _merge
0    a1    b1    c1   left_only
1    a2    b2    c2        both
2    a3    b3    c3  right_only

a = df.query('_merge == "left_only"').drop('_merge', 1)
print (a)
  col_a col_b col_c
0    a1    b1    c1

b = df.query('_merge == "right_only"').drop('_merge', 1)
print (b)
  col_a col_b col_c
2    a3    b3    c3
Run Code Online (Sandbox Code Playgroud)

或者:

a = df[df['_merge'] == "left_only"].drop('_merge', 1)
print (a)
  col_a col_b col_c
0    a1    b1    c1

b = df[df['_merge'] == "right_only"].drop('_merge', 1)
print (b)
  col_a col_b col_c
2    a3    b3    c3
Run Code Online (Sandbox Code Playgroud)


piR*_*red 5

用途pd.DataFrame.drop_duplicates
这假设行在其各自的数据框中是唯一的。

df_a.append(df_b).drop_duplicates(keep=False)

  col_a col_b col_c
0    a1    b1    c1
1    a3    b3    c3
Run Code Online (Sandbox Code Playgroud)

您甚至可以pd.concatkeys参数一起使用来提供该行所在的上下文。

pd.concat([df_a, df_b], keys=['a', 'b']).drop_duplicates(keep=False)

    col_a col_b col_c
a 0    a1    b1    c1
b 1    a3    b3    c3
Run Code Online (Sandbox Code Playgroud)