2017-03-06 36 views
-1

我正在用两个系统的数据加入两个表。一个简单的熊猫合并两个DF之间将不会兑现更复杂的规则(除非我使用它错误,不明白流程合并实施 - 很可能)。什么是一种更有效的方式来合并行的DataFrames的行与条件?

我拼凑起来的一个玩具的解决方案,让我解压2个DF与itertuples,验证基于价值观的匹配,然后重新包装成一个数据帧:

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()是低效的,因为我遍历数据2/DF2的数据1的每个条目。一旦我与data2/df2进行了很好的匹配,该行就应该被删除。

// UPDATE(显示我的问题的由来)

数据的我和合并两个独立的系统不共享任何按键或其它序列化的ID工作类型的一个例子。由于我不能完全匹配,我必须依靠逻辑/算术运算和消除过程。

在以下示例中,简单的pandas.merge在Line3上失败,因为Time1 < Time2。

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 
[...] 

// UPDATE2 我在回答建议merge_asof()join()几个置换工作。每种方法也按照文档的指示进行排序。假设我已经正确实现的每个,下面百分比是True比赛规则((时间1> =时间2)&(共1页==共2条)出的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子句中的文档状态为“调用者的列在其他索引中加入,否则加入index-on-index。如果给出多个列,则传递的DataFrame必须具有MultiIndex。”

我试着join与(时间,总计)和公正(时间)的多指标。问题在于,无论你加入什么联盟,联合会都会遭到破坏。没有什么可以执行错误分析了,因为这些索引合并为一个。

我的天真intertuple解决方案(以上)只产生完美匹配,但解决方案仍然需要一个收藏家错过的比赛。

+0

我读过这个问题多次和我还在努力了解哪里像“总”这样的东西来自于。鉴于你原来的(更新前)问题,我只需要做一些类似于'pd.merge_asof(df1,df2,left_on ='A',right_on ='B',left_by ='X',right_by ='Y',allow_exact_matches =假,方向='前进')'。请注意,'direction'参数在pandas 0.20.0之前不会出现,因此您必须从源代码构建熊猫或暂时保持紧密。 – chrisaycock

+0

@chrisaycock,你必须用一点想象力来理解我朴素的算法和我上面所说的原始数据之间的关系。道达尔就是这样 - 在未集成的交易系统之间传播的单个交易的总和。为了让我的代码更容易遵循,我选择了A/B作为命令,X/Y作为匹配。 'merge_asof()'没有出现在我的搜索之前。 'direction'参数非常重要,我只注意到'tolerance'参数,使'merge_asof'成为解决方案的绝佳选择。更多测试。 – xtian

回答

0

df3 = df1.join(df2)不能做你想要的吗?

+0

没有。在上面的例子中,一个简单的连接会给(5,15)&(4,15),但是这不符合规则5 <4。 – xtian

0

如果我正确理解你的逻辑,这应该这样做:

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 
+0

TLDR:陪审团仍在审议中;我在上面添加了一些错误检查结果。 merge_asof()做了很多很好的匹配,但是时间匹配中的错误带来了整体良好的匹配。今天,我做了让每种合并类型运行的繁重工作;之后我必须回到项目中来检查我的方法 - 确保没有错误。 – xtian

相关问题