簡體   English   中英

兩個或多個數據幀的完全外連接

[英]Full outer join of two or more data frames

給定以下三個Pandas數據幀,我需要將它們合並為類似於SQL全外連接。 注意,密鑰是多索引type_Nid_NN = 1,2,3:

import pandas as pd

raw_data = {
        'type_1': [0, 1, 1,1],
        'id_1': ['3', '4', '5','5'],
        'name_1': ['Alex', 'Amy', 'Allen', 'Jane']}
df_a = pd.DataFrame(raw_data, columns = ['type_1', 'id_1', 'name_1' ])

raw_datab = {
        'type_2': [1, 1, 1, 0],
        'id_2': ['4', '5', '5', '7'],
        'name_2': ['Bill', 'Brian', 'Joe', 'Bryce']}
df_b = pd.DataFrame(raw_datab, columns = ['type_2', 'id_2', 'name_2'])

raw_datac = {
        'type_3': [1, 0],
        'id_3': ['4', '7'],
        'name_3': ['School', 'White']}
df_c = pd.DataFrame(raw_datac, columns = ['type_3', 'id_3', 'name_3'])

預期結果應該是:

type_1   id_1   name_1   type_2   id_2   name_2   type_3   id_3   name_3
0        3      Alex     NaN      NaN    NaN      NaN      NaN    NaN
1        4      Amy      1        4      Bill     1        4      School
1        5      Allen    1        5      Brian    NaN      NaN    NaN
1        5      Allen    1        5      Joe      NaN      NaN    NaN
1        5      Jane     1        5      Brian    NaN      NaN    NaN
1        5      Jane     1        5      Joe      NaN      NaN    NaN
NaN      NaN    NaN      0        7      Bryce    0        7      White

如何在熊貓中實現這一目標?

我建議你讓生活變得不那么復雜,並且你想要合並的東西沒有不同的名字。

da = df_a.set_index(['type_1', 'id_1']).rename_axis(['type', 'id'])
db = df_b.set_index(['type_2', 'id_2']).rename_axis(['type', 'id'])
dc = df_c.set_index(['type_3', 'id_3']).rename_axis(['type', 'id'])

da.join(db, how='outer').join(dc, how='outer')

        name_1 name_2  name_3
type id                      
0    3    Alex    NaN     NaN
     7     NaN  Bryce   White
1    4     Amy   Bill  School
     5   Allen  Brian     NaN
     5   Allen    Joe     NaN
     5    Jane  Brian     NaN
     5    Jane    Joe     NaN

這是獲取其他專欄的令人討厭的方法

from cytoolz.dicttoolz import merge

i = pd.DataFrame(d.index.values.tolist(), d.index, d.index.names)
d = d.assign(**merge(
    i.mask(d[f'name_{j}'].isna()).add_suffix(f'_{j}').to_dict('l')
    for j in [1, 2, 3]
))

d[sorted(d.columns, key=lambda x: x.split('_')[::-1])]

        id_1 name_1  type_1 id_2 name_2  type_2 id_3  name_3  type_3
type id                                                             
0    3     3   Alex     0.0  NaN    NaN     NaN  NaN     NaN     NaN
     7   NaN    NaN     NaN    7  Bryce     0.0    7   White     0.0
1    4     4    Amy     1.0    4   Bill     1.0    4  School     1.0
     5     5  Allen     1.0    5  Brian     1.0  NaN     NaN     NaN
     5     5  Allen     1.0    5    Joe     1.0  NaN     NaN     NaN
     5     5   Jane     1.0    5  Brian     1.0  NaN     NaN     NaN
     5     5   Jane     1.0    5    Joe     1.0  NaN     NaN     NaN

您可以使用2個連續合並,首先在df_adf_b ,然后在df_c

In [49]: df_temp = df_a.merge(df_b, how='outer', left_on=['type_1', 'id_1'], right_on=['type_2', 'id_2'])

In [50]: df_temp.merge(df_c, how='outer', left_on=['type_2', 'id_2'], right_on=['type_3', 'id_3'])
Out[50]:
   type_1 id_1 name_1 type_2 id_2 name_2  type_3 id_3  name_3
0     0.0    3   Alex    NaN  NaN    NaN     NaN  NaN     NaN
1     1.0    4    Amy      1    4   Bill     1.0    4  School
2     1.0    5  Allen      1    5  Brian     NaN  NaN     NaN
3     1.0    5  Allen      1    5    Joe     NaN  NaN     NaN
4     1.0    5   Jane      1    5  Brian     NaN  NaN     NaN
5     1.0    5   Jane      1    5    Joe     NaN  NaN     NaN
6     NaN  NaN    NaN      0    7  Bryce     0.0    7   White

讓我們嘗試為此創建一個新密鑰,我在這里使用reduce

import functools
dfs=[df_a,df_b,df_c]
dfs=[x.assign(key=list(zip(x.iloc[:,0],x.iloc[:,1]))) for x in dfs]
merged_df = functools.reduce(lambda left,right: pd.merge(left,right,on='key',how='outer'), dfs)
merged_df.drop('key',1) 
Out[110]: 
   type_1 id_1 name_1  type_2 id_2 name_2  type_3 id_3  name_3
0     0.0    3   Alex     NaN  NaN    NaN     NaN  NaN     NaN
1     1.0    4    Amy     1.0    4   Bill     1.0    4  School
2     1.0    5  Allen     1.0    5  Brian     NaN  NaN     NaN
3     1.0    5  Allen     1.0    5    Joe     NaN  NaN     NaN
4     1.0    5   Jane     1.0    5  Brian     NaN  NaN     NaN
5     1.0    5   Jane     1.0    5    Joe     NaN  NaN     NaN
6     NaN  NaN    NaN     0.0    7  Bryce     0.0    7   White

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM