#python-3.x #pandas #performance #logging
Вопрос:
Я анализирую журналы, и у меня есть идентификатор пользователя, время покупки и сумма покупки в первой таблице, а также временной интервал посещения и идентификатор во второй.
Первая таблица содержит около 90 тысяч строк, во второй-около 1 миллиона. Мне нужно найти доходы во второй таблице, если:
- Совпадающие идентификаторы
- Покупка происходит в течение временного интервала сеанса из таблицы 1
Я написал этот код:
for i in range(len(data_purchases)):
rowIndex = data_visits[(data_visits['uid'] == data_purchases['uid'].iloc[i]) amp;
(data_visits['start_ts_dt'] < data_purchases['buy_ts'].iloc[i]) amp;
(data_visits['end_ts_dt'] > data_purchases['buy_ts'].iloc[i])].index
data_visits.loc[rowIndex, 'Revenue'] = data_purchases['revenue'].iloc[i]
Но это действительно медленно. Есть ли какой-нибудь способ ускорить этот процесс?
Ответ №1:
Вы можете выполнить слияние слева по 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
Комментарии:
1. Спасибо за ваш ответ! Но этот метод удаляет все значения из data_visits, которые не входят в data_purchases, однако мне также нужна информация о сеансах, в которых не было покупок
2. Я добавил пример —
data_visits
сохраняет все исходные строки.