Можно ли заменить этот вложенный l oop в pandas векторизацией numpy для ускорения обработки кода? - PullRequest
0 голосов
/ 16 июня 2020

Данные:

orderid         shopid  userid      event_time            timestamp 
31077182438530  10151   154282716   2019-12-27 00:33:02   1577406782    
31078679118082  10151   154282716   2019-12-27 00:58:00   1577408280    
31079250834942  10151   154282716   2019-12-27 01:07:30   1577408850    
31086252001110  10151   12825914    2019-12-27 03:04:12   1577415852    
31087365203493  10151   102963110   2019-12-27 03:22:46   1577416966    

Текущий код:

shopid = df.shopid.values
userid = df.userid.values
event_time = df.timestamp.values
flag = np.zeros(shopid.shape, dtype=int)

current_shop = 0
for i in range(len(df)):
    if shopid[i] != current_shop:
        current_shop = shopid[i]
        prev_time = event_time[i] - 3600
        users = {userid[i]: 1}
    for j in range(i+1, len(df)):
        if (current_shop == shopid[j]) and (event_time[j] - event_time[i] <= 3600):
            if userid[j] not in users:
                users[userid[j]] = 0
            users[userid[j]] += 1
        else:
            break
    while j - i / len(users) < 3 and event_time[j-1] - prev_time > 3600:
        j -= 1
        users[userid[j]] -= 1
        if users[userid[j]] == 0:
            users.pop(userid[j])
    if j - i / len(users) >= 3:
        flag[i:j] = 1
    prev_time = event_time[i]    

В основном то, что я пытаюсь сделать, это найти для каждого магазина, какой пользователь сделал 3 или более заказов в течение 1 часа любого интервала. Итак, выше я просматриваю каждый магазин (1-й l oop), затем перебираю заказы каждого магазина (2-й l oop) и проверяю, находится ли время в пределах 1 часа, затем добавляю пользователя в dict с подсчетом заказов. После этого я делаю декрементальный l oop (3-й l oop), чтобы подсчитать количество заказов / уникальных пользователей, и если меньше 3, я вытолкну пользователя из dict. В конце проверьте наличие противоположного условия, и, если оно действительно, я устанавливаю флаг в 1. Затем флаг используется для идентификации указанного c идентификатора заказа, соответствующего магазина и идентификатора пользователя.

Ожидаемый результат:

orderid         shopid  userid      event_time            timestamp     flag
31077182438530  10151   154282716   2019-12-27 00:33:02   1577406782    1
31078679118082  10151   154282716   2019-12-27 00:58:00   1577408280    1
31079250834942  10151   154282716   2019-12-27 01:07:30   1577408850    1
31086252001110  10151   12825914    2019-12-27 03:04:12   1577415852    0
31087365203493  10151   102963110   2019-12-27 03:22:46   1577416966    0

1 Ответ

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

Можете ли вы попробовать это?

df['event_time'] = pd.to_datetime(df['event_time'])

Это должно дать вам счет для каждого магазина с почасовой частотой

df.groupby(['shopid','userid', pd.Grouper(key='event_time',freq='H')]).count()

df['flag'] = df.groupby(['shopid','userid', pd.Grouper(key='event_time',freq='H')])['userid'].count().values

Вот на выходе я получил

shopid  userid  event_time  orderid timestamp
0   10151   12825914    2019-12-27 03:00:00 1   1
1   10151   12825914    2019-12-27 07:00:00 1   1
2   10151   102963110   2019-12-27 03:00:00 1   1
3   10151   102963110   2019-12-27 04:00:00 1   1
4   10151   154282716   2019-12-27 00:00:00 2   2
5   10151   154282716   2019-12-27 01:00:00 1   1
6   10151   154282716   2019-12-27 03:00:00 1   1
7   10151   154282716   2019-12-27 04:00:00 1   1
8   10151   154282716   2019-12-27 14:00:00 1   1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...