Лучший способ установить подкадр данных, когда индексы перекрываются? - PullRequest
0 голосов
/ 01 апреля 2020

Общий вопрос: Какой самый быстрый (или лучший альтернативный) способ создания нескольких подмножеств из кадра данных, когда индексы перекрываются?

Привет всем, у меня есть этот набор данных и предоставленная информация :

# %% Imports
import pandas as pd
import numpy as np
from faker import Faker
np.random.seed(123)
Faker.seed(123)
fake = Faker()

# %% Dataframe given
time_data = pd.date_range(start='1/1/2020', end='1/2/2020', freq='S')
df = pd.DataFrame(time_data, columns=['datetime'])
df['score'] = np.random.randint(0, 1000, size=len(time_data))
df['datetime'] = pd.to_datetime(df['datetime'])
df['datetime'] = df['datetime'].apply(lambda i: fake.date_time_between(
    start_date=i, end_date=i+pd.Timedelta(minutes=1))
    )
df['pot_eventtime'] = df['datetime'].apply(lambda i: fake.date_time_between(
    start_date=i-pd.Timedelta(seconds=2), end_date=i)
    )
df = df.sort_values(by='datetime').reset_index(drop=True)

# %% Indices and EVENTTIME given
ind1 = list(df[df['score'] > 900].index)
EVENTTIME = pd.Timedelta(seconds=5)

Теперь, учитывая список индексов и EVENTTIME », я хочу извлечь все наблюдения этого набора данных, которые связаны с каждым индексом, с учетом следующего правила:

df ['datetime'] - время события <= потенциальное_действие_i <= df ['дата / время]] </p>

, где EVENTTIME определяется как 5 секунд.

Мое решение - установить подмножество данные в a для l oop:

entities = {}
def orig(entities, EVENTTIME):
    for i in ind1:
        mask1 = (df['datetime'] - EVENTTIME) <= df.loc[i, 'pot_eventtime']
        mask2 = df['datetime'] >= df.loc[i, 'pot_eventtime']
        sub_df = df.loc[mask1 & mask2,].copy().reset_index(drop=True)
        if len(sub_df) > 0:
            entities[i] = sub_df

Однако, как и ожидалось, это чрезвычайно медленно:

In [17]: %timeit orig(entities, EVENTTIME)
35.2 s ± 443 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Мой вопрос в основном: есть ли более быстрый путь чтобы получить тот же вывод?

Теперь, прежде чем сказать просто подмножество диапазонов индекса в одном go, поймите, что эти события могут перекрываться , отсюда и сложность проблемы , Например, обратите внимание, что события 84 (5,6,7,8) и 86 (0,1,2,3) в выходных данных перекрываются. Мне нужно сохранить эту информацию (какие разделы карты данных для какого события), потому что контекст имеет значение. Поэтому подстановка исходного кадра данных по диапазонам заданного индекса не возможна.

In [18]: entities[84]
Out[18]: 
             datetime  score       pot_eventtime
0 2020-01-01 00:01:56    555 2020-01-01 00:01:56
1 2020-01-01 00:01:57    582 2020-01-01 00:01:55
2 2020-01-01 00:01:57    826 2020-01-01 00:01:55
3 2020-01-01 00:01:58    950 2020-01-01 00:01:56
4 2020-01-01 00:01:59    489 2020-01-01 00:01:57
5 2020-01-01 00:02:00    940 2020-01-01 00:02:00
6 2020-01-01 00:02:01    390 2020-01-01 00:01:59
7 2020-01-01 00:02:01    967 2020-01-01 00:01:59
8 2020-01-01 00:02:01    484 2020-01-01 00:02:00

In [19]: entities[86]
Out[19]: 
             datetime  score       pot_eventtime
0 2020-01-01 00:02:00    940 2020-01-01 00:02:00
1 2020-01-01 00:02:01    390 2020-01-01 00:01:59
2 2020-01-01 00:02:01    967 2020-01-01 00:01:59
3 2020-01-01 00:02:01    484 2020-01-01 00:02:00
4 2020-01-01 00:02:02    154 2020-01-01 00:02:00
5 2020-01-01 00:02:02    244 2020-01-01 00:02:01
6 2020-01-01 00:02:04    180 2020-01-01 00:02:04
7 2020-01-01 00:02:04    357 2020-01-01 00:02:02
8 2020-01-01 00:02:05    262 2020-01-01 00:02:03
9 2020-01-01 00:02:05    255 2020-01-01 00:02:05
...