使用条件逐行合并数据帧中的行的更有效方法是什么?



我正在将两个表与来自两个系统的数据一起加入。一个简单的熊猫合并在两个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

最新更新