更快速地关联两个pandas DataFrames?

时间:2017-12-01 07:40:50

标签: python pandas numpy

我有两只pandas Dataframes:

  

自动化

index   id  user_id merchant_id marketing_email_id  start_date  end_date    email_status    created_at
0   133198  133199  10939   88  681 2016-06-29  2016-07-06  1   2016-06-29 11:26:46
1   578787  578788  226281  745 1636    2017-09-14  2017-09-21  0   2017-09-14 12:32:32
2   222373  222374  86557   37  1274    2016-12-31  2017-01-07  0   2016-12-31 13:31:18
3   279039  279040  92109   669 1470    2017-03-01  2017-03-15  0   2017-03-01 12:09:27
4   33913   33914   25422   155 652 2016-02-22  2016-02-27  1   2016-02-22 12:45:15
5   423084  423085  29820   509 2067    2017-06-19  2017-06-20  1   2017-06-19 10:00:43
6   592752  592753  368756  1310    2827    2017-09-21  2017-09-28  0   2017-09-21 06:03:49
7   660899  660900  13007   206 2189    2017-10-19  2017-10-26  0   2017-10-19 07:47:48
8   491336  491337  125266  745 1626    2017-07-26  2017-08-02  0   2017-07-26 11:31:28
9   424653  424654  115139  687 1832    2017-06-20  2017-06-27  0   2017-06-20 07:33:03
  

访问

    user_id merchant_id visit_verified
created_at          
2015-02-09 10:57:05 57  29  1
2015-02-09 14:23:12 58  30  1
2015-02-09 14:29:14 58  30  1
2015-02-09 14:51:26 59  30  1
2015-02-09 16:14:50 60  29  1
2015-02-09 16:17:22 61  30  1
2015-02-09 17:44:20 62  30  1
2015-02-09 17:46:57 63  30  1
2015-02-09 17:53:26 60  29  1
2015-02-09 18:03:40 64  29  1

我正在尝试关联自动化表中的每一行,如果访问表中有相应的行,则created_at位于start_date和end_date之间。

以下是用于计算它的代码:

automate.iloc[1,"visit"] = visits[visits.user_id.isin([automate.iloc[1].user_id])][automate.iloc[1].start_date:automate.iloc[1].end_date].index.values

在自动化表中为所有 700k行复制上述内容时出现问题。 迭代自动化表中的每一行似乎非常慢。我使用了 df.iterrows 函数,但我无法为每一行赋值。

我可以使用更快的方法来处理上述逻辑吗?

编辑1: 预期的输出应该是

index   id  user_id merchant_id marketing_email_id  start_date  end_date    email_status    created_at  Visit
0   133198  133199  10939   88  681 2016-06-29  2016-07-06  1   2016-06-29 11:26:46 NaN
1   578787  578788  226281  745 1636    2017-09-14  2017-09-21  0   2017-09-14 12:32:32 NaN
2   222373  222374  86557   37  1274    2016-12-31  2017-01-07  0   2016-12-31 13:31:18 NaN
3   279039  279040  92109   669 1470    2017-03-01  2017-03-15  0   2017-03-01 12:09:27 NaN
4   33913   33914   25422   155 652 2016-02-22  2016-02-27  1   2016-02-22 12:45:15 NaN

如果给定用户在开始日期内访问,则NaN值可能会或可能不会填充时间戳值。

1 个答案:

答案 0 :(得分:0)

嗯,是的,这是一个艰难的。我唯一的建议是按日期/时间排序两个数据帧,然后......这里有一些伪代码:

dfautomate2 = dfautomate.sortby(start_date)
dfvisit = dfvisit.sortby(created_at)
listofawesome = []
for visit in dfvisit:
    for event_range in dfautomate2:
        if event_range.start_date < visit.created_at < event_range.end_date:
            print("WINNING")
            listofawesome.append(event_range)
        else:
            dfautomate[event_range].delete #its been a while since I used pandas, but you get the idea

绝对不是最漂亮的,并且可能有更快/更好的方法。

这个想法是,如果两个数据帧都是从最新到最旧排序,并且您经历了访问,如果您总是在最早的访问中,则可以删除自动化df中之前的那些行...那样在下一个for循环中,你不必在上次访问之前检查它们,因为它们已经通过了。

可能不适合你的情况,但是如果你想出一个解决方案的话,知道这是一个很好的解决方案。