pandas:加入两个 table 并在没有匹配项时填充值
pandas: join two table and populate value when even there is not a match
不确定我应该如何描述这个问题,所以我将在下面使用一个例子。
我想加入以下两个 table df1 和 df2 以获得像 df3 这样的 table,其中所有 ID、A、B、C、D 都需要在每个时间出现。
d1 = {'Time': [1,1,2,2], 'BinID': ['x']*4, 'V1': [25, 30, 22, 28], 'ID': ['A','B']*2}
df1 = pd.DataFrame(d1)
BinID ID Time V1
0 x A 1 25
1 x B 1 30
2 x A 2 22
3 x B 2 28
d2 = {'BinID': ['x']*4, 'ID': ['A','B','C','D'], 'V2': [26]*4}
df2= pd.DataFrame(d2)
BinID ID V2
0 x A 26
1 x B 26
2 x C 26
3 x D 26
我想得到这样的东西:
BinID_x ID V2 BinID_y Time V1
0 x A 26 x 1 25
1 x B 26 x 1 30
2 x C 26 x 1 NaN
3 x D 26 x 1 NaN
4 x A 26 x 2 22
5 x B 26 x 2 28
6 x C 26 x 2 NaN
7 x D 26 x 2 NaN
但是 left join 只会让我得到这个...
pd.merge(df2, df1, on = 'ID', how = 'left')
BinID_x ID V2 BinID_y Time V1
0 x A 26 x 1 25
1 x A 26 x 2 22
2 x B 26 x 1 30
3 x B 26 x 2 28
4 x C 26 NaN NaN NaN
5 x D 26 NaN NaN NaN
我认为问题不在于合并,而是您需要定义缺少的值。我会通过制作一个中间数据框来做到这一点,该数据框包含您希望出现在最终数据框中的所有时间和 ID 组合:
df1a = pd.DataFrame({'Time': [1,1,2,2], 'BinID': ['x']*4,
'V1': [25, 30, 22, 28], 'ID': ['A','B']*2})
df1b = pd.DataFrame({'Time': [1]*4+[2]*4, 'ID': list('ABCD')*2 })
df1 = pd.merge( df1b, df1a, on=['Time','ID'], how='left' )
df1b
ID Time
0 A 1
1 B 1
2 C 1
3 D 1
4 A 2
5 B 2
6 C 2
7 D 2
其余代码相同并生成:
pd.merge(df2, df1, on = 'ID', how = 'outer').sort(['Time','ID'])
BinID_x ID V2 Time BinID_y V1
0 x A 26 1 x 25
2 x B 26 1 x 30
4 x C 26 1 NaN NaN
6 x D 26 1 NaN NaN
1 x A 26 2 x 22
3 x B 26 2 x 28
5 x C 26 2 NaN NaN
7 x D 26 2 NaN NaN
不确定我应该如何描述这个问题,所以我将在下面使用一个例子。 我想加入以下两个 table df1 和 df2 以获得像 df3 这样的 table,其中所有 ID、A、B、C、D 都需要在每个时间出现。
d1 = {'Time': [1,1,2,2], 'BinID': ['x']*4, 'V1': [25, 30, 22, 28], 'ID': ['A','B']*2}
df1 = pd.DataFrame(d1)
BinID ID Time V1
0 x A 1 25
1 x B 1 30
2 x A 2 22
3 x B 2 28
d2 = {'BinID': ['x']*4, 'ID': ['A','B','C','D'], 'V2': [26]*4}
df2= pd.DataFrame(d2)
BinID ID V2
0 x A 26
1 x B 26
2 x C 26
3 x D 26
我想得到这样的东西:
BinID_x ID V2 BinID_y Time V1
0 x A 26 x 1 25
1 x B 26 x 1 30
2 x C 26 x 1 NaN
3 x D 26 x 1 NaN
4 x A 26 x 2 22
5 x B 26 x 2 28
6 x C 26 x 2 NaN
7 x D 26 x 2 NaN
但是 left join 只会让我得到这个...
pd.merge(df2, df1, on = 'ID', how = 'left')
BinID_x ID V2 BinID_y Time V1
0 x A 26 x 1 25
1 x A 26 x 2 22
2 x B 26 x 1 30
3 x B 26 x 2 28
4 x C 26 NaN NaN NaN
5 x D 26 NaN NaN NaN
我认为问题不在于合并,而是您需要定义缺少的值。我会通过制作一个中间数据框来做到这一点,该数据框包含您希望出现在最终数据框中的所有时间和 ID 组合:
df1a = pd.DataFrame({'Time': [1,1,2,2], 'BinID': ['x']*4,
'V1': [25, 30, 22, 28], 'ID': ['A','B']*2})
df1b = pd.DataFrame({'Time': [1]*4+[2]*4, 'ID': list('ABCD')*2 })
df1 = pd.merge( df1b, df1a, on=['Time','ID'], how='left' )
df1b
ID Time
0 A 1
1 B 1
2 C 1
3 D 1
4 A 2
5 B 2
6 C 2
7 D 2
其余代码相同并生成:
pd.merge(df2, df1, on = 'ID', how = 'outer').sort(['Time','ID'])
BinID_x ID V2 Time BinID_y V1
0 x A 26 1 x 25
2 x B 26 1 x 30
4 x C 26 1 NaN NaN
6 x D 26 1 NaN NaN
1 x A 26 2 x 22
3 x B 26 2 x 28
5 x C 26 2 NaN NaN
7 x D 26 2 NaN NaN