首页 > 解决方案 > 在 Python 中查找值的更快方法

问题描述

我正在分析日志,我在第一个表中有用户 ID、购买时间和购买金额,在第二个表中有访问的时间间隔和 ID。

第一个表包含大约 90k 行,第二个大约 100 万行。如果出现以下情况,我需要在第二张表中查找收入:

  1. 匹配的 ID
  2. 购买是在表 1 的会话的时间间隔内

我写了这段代码:

for i in range(len(data_purchases)):
    rowIndex = data_visits[(data_visits['uid'] == data_purchases['uid'].iloc[i]) &                             
    (data_visits['start_ts_dt'] < data_purchases['buy_ts'].iloc[i]) & 
    (data_visits['end_ts_dt'] > data_purchases['buy_ts'].iloc[i])].index
    data_visits.loc[rowIndex, 'Revenue'] = data_purchases['revenue'].iloc[i]

但它真的很慢。有什么方法可以让这个过程更快吗?

标签: python-3.xpandasperformancelogging

解决方案


uid您可以在列上执行左合并

data_visits.merge(data_purchases, on='uid', how='left')

过滤掉与您的区间条件匹配的行并提取revenue

.query('start_ts_dt < buy_ts < end_ts_dt')['revenue']

重命名它以匹配您要更新的列。

.rename('Revenue')

最后将其传递给update()您要修改的数据框的方法。

data_visits.update((
    data_visits
        .merge(data_purchases, on='uid', how='left')
        .query('start_ts_dt < buy_ts < end_ts_dt')['revenue']
        .rename('Revenue')
))

例子:

>>> data_visits
   uid  start_ts_dt  end_ts_dt  Revenue
0    0           10         20       30
1    1          900       1001        9
2    2           10         20       10
3    3          100       1010      200
>>> data_purchases
   uid  buy_ts      revenue
0    1    1000  NEW REVENUE
1    2    1001           50
>>> data_visits.update((
...     data_visits
...         .merge(data_purchases, on='uid', how='left')
...         .query('start_ts_dt < buy_ts < end_ts_dt')['revenue']
...         .rename('Revenue')
... ))
>>> data_visits
   uid  start_ts_dt  end_ts_dt      Revenue
0    0           10         20           30
1    1          900       1001  NEW REVENUE
2    2           10         20           10
3    3          100       1010          200

推荐阅读