熊猫concat vs与M:M关系合并

时间:2019-03-19 17:54:28

标签: python pandas dataframe

使用熊猫0.24.2。 Merge, join & concatenate doc表示merge方法正在调用concat()函数。我正在以M:M关系加入两个DataFrame,并希望更好地了解concat()函数的工作方式。这段代码调用merge()方法并返回预期结果:

>>> import pandas as pd
>>> left = pd.DataFrame([['001', 4123],
...                      ['001', 4855],
...                      ['001', 4761],
...                      ['002', 4991],
...                      ['003', 5001],
...                      ['004', 3999],
...                      ['004', 4175],
...                      ['004', 4101]],
...         columns=['ID', 'Value_l'])
>>> right = pd.DataFrame([['004', 1111],
...                       ['004', 1234],
...                       ['004', 1133],
...                       ['002', 1921],
...                       ['003', 2001],
...                       ['001', 2222]],
...         columns=['ID', 'Value_r'])

>>> merge_lr = pd.merge(left, right, how='outer', sort=True)
>>> print(merge_lr)
     ID  Value_l  Value_r
0   001     4123     2222
1   001     4855     2222
2   001     4761     2222
3   002     4991     1921
4   003     5001     2001
5   004     3999     1111
6   004     3999     1234
7   004     3999     1133
8   004     4175     1111
9   004     4175     1234
10  004     4175     1133
11  004     4101     1111
12  004     4101     1234
13  004     4101     1133

如何组装调用concat()函数的相同输出DataFrame?显然,此示例是错误的:

>>> merge_lr2 = pd.concat([left, right], axis=0, join='outer', sort=True, ignore_index=True)
>>> print(merge_lr2)
     ID  Value_l  Value_r
0   001   4123.0      NaN
1   001   4855.0      NaN
2   001   4761.0      NaN
3   002   4991.0      NaN
4   003   5001.0      NaN
5   004   3999.0      NaN
6   004   4175.0      NaN
7   004   4101.0      NaN
8   004      NaN   1111.0
9   004      NaN   1234.0
10  004      NaN   1133.0
11  002      NaN   1921.0
12  003      NaN   2001.0
13  001      NaN   2222.0

我可以使用concat()函数对具有M:M关系的DataFrame执行完全外部联接吗?

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解这个问题。这两种方法旨在做不同的事情并给出不同的结果。如果要合并通用键上的数据帧,请使用merge()。如果要将所有数据从一个添加到另一个,请使用concat()。我能找到的最接近合并数据框的是以下位置,但不包括左右之间重复和/或丢失的ID,以及基于排序的不同值:

merge_lr2 = pd.concat([left, right], axis=0, join='outer', sort=True, ignore_index=True)\
            .sort_values(['ID','Value_l','Value_r'])\
            .fillna(method='ffill')\
            .fillna(method='bfill')
print(merge_lr2)

     ID  Value_l  Value_r
0   001   4123.0   2222.0
2   001   4761.0   2222.0
1   001   4855.0   2222.0
13  001   4855.0   2222.0
3   002   4991.0   2222.0 <<<
11  002   4991.0   1921.0
4   003   5001.0   1921.0 <<<
12  003   5001.0   2001.0
5   004   3999.0   2001.0
7   004   4101.0   2001.0
6   004   4175.0   2001.0
8   004   4175.0   1111.0
10  004   4175.0   1133.0
9   004   4175.0   1234.0