Подсчитайте различные действия в течение одного часа в python - PullRequest
0 голосов
/ 19 июня 2020

Я начинаю работать с временными рядами. У меня есть один из пользователей, выполняющих банковские переводы в разные страны, однако наиболее частой страной, в которую он / она выполняет переводы, является X, но есть переводы также в страны Y и Z. Допустим:

date                           id       country
2020-01-01T00:00:00.000Z       id_01     X
2020-01-01T00:20:00.000Z       id_02     X
2020-01-01T00:25:00.000Z       id_03     Y
2020-01-01T00:35:00.000Z       id_04     X
2020-01-01T00:45:00.000Z       id_05     Z
2020-01-01T01:00:00.000Z       id_06     X
2020-01-01T10:20:00.000Z       id_07     X
2020-01-01T10:25:00.000Z       id_08     X
2020-01-01T13:00:00.000Z       id_09     X
2020-01-01T18:45:00.000Z       id_10     Z
2020-01-01T18:55:00.000Z       id_11     X

Поскольку наиболее частой страной является X, я хотел бы итеративно подсчитать, сколько транзакций было выполнено в течение одного часа (во всем списке событий) в странах, отличных от X.

Формат ожидаемый результат для этого конкретного случая будет:

date                           id        country
2020-01-01T00:25:00.000Z       id_03     Y
2020-01-01T00:45:00.000Z       id_05     Z

Начиная с 2020-01-01T00:00:00.000Z, в течение одного часа происходит две транзакции Y, Z. Затем, начиная с 2020-01-01T00:20:00.000Z, в течение часа происходят такие же транзакции и так далее. Затем, начиная с 2020-01-01T10:20:00.000Z, в течение одного часа все являются X. Начиная с 2020-01-01T18:45:00.000Z, в течение одного часа есть только один Z.

Я пытаюсь с двойным для l oop и .value_counts (), но я не уверен, что делаю.

Ответы [ 3 ]

2 голосов
/ 23 июня 2020

Думали ли вы об использовании для этого базы данных временных рядов? Это могло бы облегчить вашу жизнь, если бы вы выполняли много агрегатов на основе событий с произвольными временными интервалами. Базы данных временных рядов абстрагируют это для вас, поэтому все, что вам нужно, это отправить запрос и получить результаты в pandas. Он также будет работать значительно быстрее.

Например, почасовое агрегирование может быть выполнено с использованием следующего синтаксиса в QuestDB.

select timestamp, country, count() from yourTable SAMPLE BY 1h

это вернет такие результаты

| timestamp           | country | count |
| 2020-06-22T00:00:00 | X       | 234   |
| 2020-06-22T00:00:00 | Y       | 493   |
| 2020-06-22T01:00:00 | X       |  12   |
| 2020-06-22T01:00:00 | Y       |  66   |

Вы можете настроить это на ежемесячные, еженедельные или 5-минутные результаты разрешения без необходимости переписывать логи c, все, что вам нужно сделать, это изменить 1h на 1M, 7d или 5m или передайте это как аргумент.

Теперь, чтобы получить результаты за час до и после отметки времени вашей целевой транзакции, вы можете добавить поиск интервала временной отметки к вышеуказанному. Например, если ваша целевая транзакция произошла на 2010-01-01T06:47:00.000000Z, результат поиска будет

select hour, country, count() from yourTable 
where timestamp = '2010-01-01T05:47:00.000000Z;2h' 
sample by 1h; 

. Если это что-то, что вам подойдет, есть руководство о том, как запустить этот тип запроса в QuestDB. и получите результат в pandas здесь

0 голосов
/ 19 июня 2020

IIU C, вы можете выбрать только строки, а не X, затем использовать diff один раз вперед и один раз назад (в течение 1 часа до и после), и вы хотите, чтобы любое из двух различий было ниже Timedelta от 1ч.

#convert to datetime
df['date'] = pd.to_datetime(df['date'])

#mask not X and select only these rows
mX = df['country'].ne('X')
df_ = df[mX].copy()

# mask within an hour before and after 
m1H = (df_['date'].diff().le(pd.Timedelta(hours=1)) | 
        df_['date'].diff(-1).le(pd.Timedelta(hours=1)) )

# selet only the rows meeting criteria on X and 1H
df_ = df_[m1H]
print (df_)
                       date     id country
2 2020-01-01 00:25:00+00:00  id_03       Y
4 2020-01-01 00:45:00+00:00  id_05       Z
0 голосов
/ 19 июня 2020

Вы можете попробовать:

df['date'] = pd.to_datetime(df.date)
(df.country != 'X').groupby(by=df.date.dt.hour).sum()

Сначала он превращает ваши столбцы даты в datetime. Затем вы проверяете, является ли страна «X», группируете по часам и суммируете количество стран, которые отличаются от «X». Группы основаны на часах, а не на прошедшем времени. Надеюсь, это решит вашу проблему!

...