Python - векторизованная разница дат в двух фреймах данных с миллионами строк - PullRequest
0 голосов
/ 23 июня 2018

У меня есть два кадра данных:

Date                  Variable
2013-04-01 05:00:00     S   
2013-04-01 05:00:00     A   
2013-04-01 05:10:00     S   
2013-04-01 05:20:00     A
2013-04-01 05:25:00     S   
2013-04-01 05:35:00     S

И:

Date                  Variable
2013-04-01 04:50:00     A   
2013-04-01 05:00:00     A   
2013-04-01 05:05:00     S   
2013-04-01 05:15:00     S
2013-04-01 05:35:00     S   
2013-04-01 05:40:00     S

Моя цель - подсчитать количество дат в первом кадре данных за 20 минут до и 20 минут после каждой даты ввторой кадр данных.Итак, что мне нужно сделать, это перебрать все даты на втором кадре данных и посчитать, сколько дат в первом кадре данных, через 20 минут до и 20 минут после каждой конкретной даты.Кроме того, я хочу учесть количество вхождений переменной A или S, другими словами, столбцы Nr_var_20_bef имеют количество дат 20 минут перед той же переменной).Таким образом, вывод будет выглядеть примерно так:

Date               Variable   Nr_20_bef   Nr_20_aft  Nr_var_20_bef  Nr_var_20_after  
2013-04-01 04:50:00     A        0            3             0             1
2013-04-01 05:00:00     A        2            4             1             2
2013-04-01 05:05:00     S        2            3             1             2
2013-04-01 05:15:00     S        3            3             2             2
2013-04-01 05:35:00     S        3            1             2             1
2013-04-01 05:40:00     S        3            0             2             0

Моя основная проблема состоит в том, что оба фрейма данных имеют более 1 миллиона строк, и это означает, что я не могу использовать цикл for или применить панды, потому что онизанять слишком много времени с такими огромными кадрами данных.Заранее большое спасибо.

1 Ответ

0 голосов
/ 25 июня 2018

Это сложная проблема! Я могу предложить вам частичное решение, которое, надеюсь, будет достаточным для начала работы.

Вам следует изучить rolling методы панд, которые могут использовать ваш индекс DateTime. Обратите внимание, что, насколько я знаю, функции прокрутки могут смотреть только на предыдущий период, а не на будущий период. Это решение вычисляет количество экземпляров столбца bar, которое появилось за последние 20 минут, в соответствии с набором времени объединения foo и bar, которое, как я полагаю, является тем, о чем вы просите.

import pandas as pd
import numpy as np

# Attempting to generate some similar data
np.random.seed(0)
rng = pd.date_range('4/1/2013', periods=1000, freq='5T', name='Date')
df = pd.DataFrame({'Variable': np.random.choice(['S', 'A'], 1000)}, index=rng)
df1 = df.sample(frac=0.5)
df2 = df.sample(frac=0.5)

merged = df1.merge(df2, how='outer', left_index=True, right_index=True, suffixes=['_foo', '_bar'])

# pandas can't found objects, but can count bools
m = merged.notnull()

# Rolling functions can't count "after", only "before" or "center"
merged['Nr_20_bef'] = m.Variable_bar.rolling('20T').sum()

print(merged.head(10))

                    Variable_foo Variable_bar  Nr_20_bef
# Date
# 2013-04-01 00:05:00            A          NaN        0.0
# 2013-04-01 00:10:00            A          NaN        0.0
# 2013-04-01 00:15:00          NaN            S        1.0
# 2013-04-01 00:20:00            A            A        2.0
# 2013-04-01 00:25:00            A          NaN        2.0
# 2013-04-01 00:40:00          NaN            A        1.0
# 2013-04-01 00:45:00            A            A        2.0
# 2013-04-01 00:50:00          NaN            A        3.0
# 2013-04-01 01:05:00          NaN            A        2.0
# 2013-04-01 01:10:00            S            S        2.0

Генерация столбца Nr_20_bef выполняется очень быстро: ~ 1 секунда для 10 миллионов строк на моем двухлетнем ноутбуке. Например, если вы хотите считать только символы «S», вместо этого вы можете сделать m = merged == 'S'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...