我正在将两个表与来自两个系统的数据一起加入。一个简单的熊猫合并在两个DF之间不会符合更多复杂的规则(除非我使用错误的规则,否
我已经将玩具解决方案拼凑在一起,它使我可以用itertuples
解开两个DF,基于值验证匹配,然后重新包装到一个数据框中:
df1: df2:
A X B Y
0 1 10 0 2 10
1 5 15 1 4 15
2 6 15
。
df1 = pd.DataFrame(data1,columns=['A','X'])
df2 = pd.DataFrame(data2,columns=['B','Y'])
df3 = pd.DataFrame(index=['A','X','B','Y'])
i = -1
for rowA in df1.itertuples(index=False):
i += 1
for rowB in df2.itertuples(index=False):
A,X = rowA
B,Y = rowB
if (B > A) & (X==Y):
df3[i] = list(rowA+rowb)
else:
continue
print(df3.transpose())
。
A X B Y
0 1 10 2 10
1 5 15 6 15
我的天真方法是效率低下
嵌套的for()
循环效率低下,因为我在Data2/df2上为Data1的每个条目迭代。一旦我与Data2/df2匹配,则应删除该行。
//更新(显示我的问题的来源)
我正在使用的数据类型合并了两个独立系统,这些系统不共享任何键或其他序列化ID。由于我无法确切的匹配,因此我必须依靠逻辑/算术操作和消除过程。
在下面的示例中,简单的pandas.merge
在LINE3上失败,因为Time1<时间2。
Time1, Total1 ... Time2, Total2, error
1, 2017-02-19 08:03:00, 15.00 ... 2017-02-19 08:02:00, 15.00, 0
2, 2017-02-19 08:28:00, 33.00 ... 2017-02-19 08:27:00, 33.00, 0
3, 2017-02-19 08:40:00, 20.00 ... 2017-02-19 10:06:00, 20.00, 1
4, 2017-02-19 10:08:00, 20.00 ... 2017-02-19 10:16:00, 20.00, 1
[...]
应该发生的是这样的事情:
Time1, Total1 ... Time2, Total2, error
1, 2017-02-19 08:03:00, 15.00 ... 2017-02-19 08:02:00, 15.00, 0
2, 2017-02-19 08:28:00, 33.00 ... 2017-02-19 08:27:00, 33.00, 0
3, 2017-02-19 08:40:00, 20.00 ... NaN, NaN, NaN
4, 2017-02-19 10:08:00, 20.00 ... 2017-02-19 10:06:00, 20.00, 0
[...]
//更新2我已经在答案中推荐了merge_asof()
和join()
的几个排列。每种方法也按照文档指示进行排序。假设我已经正确实施了,以下百分比是规则的 True
匹配 (((time1> = time2)&(total1 == total2)在我的测试集中使用每个记录中的53个记录中的53个记录)三种方法:
| type | 'date' | 'total' | both |
|-----------------------|----------|-----------|--------|
| merg_asof sort (time) | .7924 | .9245 | .7169 |
| merg_asof (time,total)| .7735 | .6981 | .6226 |
| intertup (time,total) | .8301 | .8301 | .8301 |
| join ind (time) | na | na | na |
加入需要一个共享的密钥,对吗?文档状态中的on
子句,"呼叫者中的列(s)在其他索引上加入索引,否则将索引在索引上加入。如果给出的倍数列,则传递的数据帧必须具有多索引。" <<<<<<<<<<<<<</strong>
我尝试了join
的多指数(时间,总数)和(时间)。问题是,无论您加入什么都可以加入Clobbers。由于这些索引已合并为一个,因此没有什么可以执行错误分析的。
我的幼稚intertuple
解决方案(上图)仅产生了完美的匹配项,但是该解决方案仍然需要一个收集器进行错过的比赛。
df3 = df1.join(df2)不做您想要的?
如果我正确理解您的逻辑,则应该这样做:
time1 = pd.to_datetime(['2/19/17 8:03:00', '2/19/17 8:28:00', '2/19/17 8:40:00', '2/19/17 10:08:00'])
time2 = pd.to_datetime(['2/19/17 8:02:00', '2/19/17 8:27:00', '2/19/17 10:06:00', '2/19/17 10:16:00'])
df1 = pd.DataFrame({'Time1':time1, 'Total1':[15.00, 33.00, 20.00, 20.00]})
df2 = pd.DataFrame({'Time2':time2, 'Total2':[15.00, 33.00, 20.00, 20.00], 'error':[0,0,1,1]})
df3 = pd.merge_asof(df1, df2, left_on = 'Time1', right_on = 'Time2')
df3.loc[df3['Time2'].duplicated(), ['Time2', 'Total2', 'error']] = None
输出:
Time1 Total1 Time2 Total2 error
0 2017-02-19 08:03:00 15.0 2017-02-19 08:02:00 15.0 0.0
1 2017-02-19 08:28:00 33.0 2017-02-19 08:27:00 33.0 0.0
2 2017-02-19 08:40:00 20.0 NaT NaN NaN
3 2017-02-19 10:08:00 20.0 2017-02-19 10:06:00 20.0 1.0