import pandas as pd
import numpy as np
from collections import deque
CACHE_SIZE = 100
CACHE_LAG = 3600
class ContrFactualNext:
def __init__(self, df: pd.DataFrame):
self.df = df
self.locator = 0
self.length = self.df.shape[0]
self.preference = ''
self.recsys_list = df.logger.unique().tolist()
self.stacks = {k: deque(maxlen=CACHE_SIZE) for k in self.recsys_list}
def __iter__(self):
return self
def __len__(self) -> int:
return self.length
def __next__(self):
while self.locator < self.length:
row = self.df.iloc[self.locator]
if (self.preference == '') or (self.preference == row.logger):
# возвращаем запись из лога
self.locator += 1
return row
dq = self.stacks[self.preference]
while len(dq):
# возвращаем запись из кеша, берем самую старую
tmp = dq.popleft()
# tmp = dq.pop()
assert (row.created_at - tmp.created_at).seconds >= 0 # ожидаем, что записи отсортированы по времени
if (row.created_at - tmp.created_at).seconds < CACHE_LAG: # проверяем, что запись не слишком старая
return tmp
self.stacks[row.logger].append(row)
self.locator += 1
# добавляем запись в кеш
raise StopIteration
в preference мы указываем наши текущие пожелания - точку под какую руку бандитов хотим получить. Могу на следующем датазавтраке на примерах показать, если интересно