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