在Python上垂直外连接

时间:2015-07-13 04:58:01

标签: python

表1

Category Date           Value
A        01/01/2015       4
A        02/01/2015       1
B        01/01/2015       6
B        02/01/2015       7

上面的表1列出了按月组织的每个类别的值。

表2

Category Date           Value
A        03/01/2015       10
C        03/01/2015       66
D        03/01/2015       9

假设表2出现,其中包含2015年3月每个类别的值。

表3

Category Date           Value
A        01/01/2015       4
A        02/01/2015       1
A        03/01/2015       10
B        01/01/2015       6
B        02/01/2015       7
B        03/01/2015       0
C        01/01/2015       0
C        02/01/2015       0
C        03/01/2015       66
D        01/01/2015       0
D        02/01/2015       0
D        03/01/2015       9

我想在Python上“垂直”“外连接”这两个表: 如果Table2具有Table1没有的类别,则它将该类别添加到Table3,并为01/01/2015和02/01/2015分配值0。此外,通过为03/01/2015分配值0,表3中也将添加表1中但不在表2中的类别。如果两者具有相同的类别,则它们将垂直添加table1和table2中的值。

任何建议或帮助都将受到高度赞赏。我一整天都在考虑这个问题,但仍无法找到有效的方法。 非常感谢!

1 个答案:

答案 0 :(得分:1)

我会使用Pandas执行此操作,如下所示(我将调用您的表df1df2):

首先使用setconcat准备最终表格的日期和类别列表,以便仅选择原始表格中的唯一值:

import pandas as pd
dates = set(pd.concat([df1.Date,df2.Date]))
cats = set(pd.concat([df1.Category,df2.Category]))

然后我们通过迭代这些集来创建着陆表(itertools.product是一个巧妙的技巧,但请注意你必须将其作为列表投射到数据帧构造函数中):

df3 = pd.DataFrame(list(itertools.product(cats,dates)),columns = ['Category','Date'])
df3

Out[88]: 
   Category        Date
0         D  01/01/2015
1         D  03/01/2015
2         D  02/01/2015
3         C  01/01/2015
4         C  03/01/2015
5         C  02/01/2015
6         A  01/01/2015
7         A  03/01/2015
8         A  02/01/2015
9         B  01/01/2015
10        B  03/01/2015
11        B  02/01/2015

最后,我们使用merge(设置on='left')引入值,使用np.fmax合并两个集合(您使用fmax代替max }忽略nans):

df3['Value'] = np.fmax(pd.merge(df3,df1,how='left')['Value'],pd.merge(df3,df2,how='left')['Value'])

df3
Out[127]: 
   Category        Date  Value
0         D  01/01/2015    NaN
1         D  03/01/2015      9
2         D  02/01/2015    NaN
3         C  01/01/2015    NaN
4         C  03/01/2015     66
5         C  02/01/2015    NaN
6         A  01/01/2015      4
7         A  03/01/2015     10
8         A  02/01/2015      1
9         B  01/01/2015      6
10        B  03/01/2015    NaN
11        B  02/01/2015      7