Pandas diff SeriesGroupBy работает относительно медленно - PullRequest
0 голосов
/ 24 мая 2018
Total time: 1.01876 s
Function: prepare at line 91

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    91                                           @profile
    92                                           def prepare():
    93                                           
    94         1       5681.0   5681.0      0.6     
    95         1       2416.0   2416.0      0.2      
    96                                           
    97                                               
    98         1        536.0    536.0      0.1      tss = df.groupby('user_id').timestamp
    99         1     949643.0 949643.0     93.2      delta = tss.diff()
   100         1       1822.0   1822.0      0.2      
   101         1      13030.0  13030.0      1.3      
   102         1       5193.0   5193.0      0.5      
   103         1       1251.0   1251.0      0.1      
   104                                           
   105         1       2038.0   2038.0      0.2      
   106                                           
   107         1       1851.0   1851.0      0.2     
   108                                           
   109         1        282.0    282.0      0.0      
   110                                           
   111         1       3088.0   3088.0      0.3      
   112         1       2943.0   2943.0      0.3      
   113         1        438.0    438.0      0.0      
   114         1       4658.0   4658.0      0.5      
   115         1      17083.0  17083.0      1.7      
   116         1       3115.0   3115.0      0.3      
   117         1       3691.0   3691.0      0.4      
   118                                           
   119         1          2.0      2.0      0.0      

У меня есть фрейм данных, который я группирую по некоторому ключу, а затем выбираю столбец из каждой группы и выполняю diff для этого столбца (для каждой группы).Как показано в результатах профилирования, операция сравнения очень медленная по сравнению с остальными и является своего рода узким местом.Это ожидается?Существуют ли более быстрые альтернативы для достижения того же результата?

Редактировать: еще несколько объяснений В моем случае метки времени представляют время для некоторых действий пользователя, которому яхотите вычислить дельты между этими действиями (они отсортированы), но действия каждого пользователя полностью независимы от других пользователей.

Редактировать: Пример кода

import pandas as pd
import numpy as np


df = pd.DataFrame(
    {'ts':[1,2,3,4,60,61,62,63,64,150,155,156,
           1,2,3,4,60,61,62,63,64,150,155,163,
           1,2,3,4,60,61,62,63,64,150,155,183],
    'id': [1,2,3,4,60,61,62,63,64,150,155,156,
           71,72,73,74,80,81,82,83,64,160,165,166,
           21,22,23,24,90,91,92,93,94,180,185,186],
    'other':['x','x','x','','x','x','','x','x','','x','',
             'y','y','y','','y','y','','y','y','','y','',
             'z','z','z','','z','z','','z','z','','z',''],
    'user':['x','x','x','x','x','x','x','x','z','x','x','y',
            'y','y','y','y','y','y','y','y','x','y','y','x',
            'z','z','z','z','z','z','z','z','y','z','z','z']
    })



df.set_index('id',inplace=True)
deltas=df.groupby('user').ts.transform(pd.Series.diff)

1 Ответ

0 голосов
/ 24 мая 2018

Если вы не хотите сортировать свои данные или опускаться до numpy, то можно значительно повысить производительность, изменив серию user на Категориальная.Категориальные данные эффективно хранятся в виде целочисленных указателей.

В следующем примере я вижу улучшение с 86 мс до 59 мс.Это может улучшить в дальнейшем для больших наборов данных и где повторяются больше пользователей.

df = pd.concat([df]*10000)

%timeit df.groupby('user').ts.transform(pd.Series.diff)  # 86.1 ms per loop

%timeit df['user'].astype('category')                    # 23.4 ms per loop
df['user'] = df['user'].astype('category')
%timeit df.groupby('user').ts.transform(pd.Series.diff)  # 35.7 ms per loop

Если вы выполняете несколько операций, то одноразовая стоимость конвертации категорические можно сбрасывать со счетов.

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