Быстрая групповая работа в нескольких столбцах, где все, кроме одного, уже отсортированы - PullRequest
0 голосов
/ 28 февраля 2020

Предположим, у меня довольно большой фрейм данных, с тремя столбцами, которые я хочу сгруппировать, и тремя столбцами, которые я затем хочу суммировать. Но , я могу гарантировать, что когда я хочу go sum, два из моих трех столбцов группировки (g1, g2) гарантированно будут отсортированы в моем DataFrame. то есть

In [151]: df = pd.DataFrame(dict(g1=np.random.randint(0, 4, 5*10**6), g2=np.random.randint(0, 
     ...: 3500, 5*10**6), g3=np.random.randint(0, 3, 5*10**6), s1 = np.random.randn(5*10**6), 
     ...: s2=np.random.randn(5*10**6)*10, s3=np.random.randn(5*10**6)*100))                   
In [152]: df.head(7)                                                                         
Out[152]: 
   g1    g2  g3        s1         s2          s3
0   2  1612   1 -1.548050   9.420745  -69.687951
1   0  1626   1 -1.057544  -1.297303  -52.154033
2   1  1074   2  0.043038  11.903100  -21.904080
3   2  3227   2  1.578995  -6.869531   72.888734
4   3   991   1  0.128140   1.171708   66.079545
5   0   547   0  1.066463 -18.291128  -68.365035
6   1   439   1  0.011390   7.240739 -248.659338

In [153]: df.sort_values(by=['g1', 'g2'], inplace=True)

^ мы можем предположить, что этот отсортированный кадр данных (по g1 и g2) является моим входом.

Тогда я просто хочу:

In [149]: %timeit df.groupby(['g1', 'g2', 'g3']).sum()                                        
5.47 s ± 739 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Но, как вы видите, это довольно медленно. Я надеялся использовать тот факт, что два моих столбца группировки отсортированы, чтобы как-то ускорить эту операцию. Как я могу это сделать (с Pandas или NumPy или любой другой Python библиотекой)?


Примечания

  • Я подумал, что это может быть Быстрее оторваться от дел с двумя отсортированными групповыми столбцами ... но на самом деле для меня это выглядит немного медленнее.

    In [147]: %timeit df.groupby(['g1', 'g2', 'g3']).sum()                                        
    4.17 s ± 822 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [148]: df.sort_values(by=['g1', 'g2'], inplace=True)                                       
    
    In [149]: %timeit df.groupby(['g1', 'g2', 'g3']).sum()                                        
    5.47 s ± 739 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
  • Я попытался передать sort=False, как только у меня будет ( g1, g2) отсортировал фрейм данных, но это, похоже, не помогло.

    In [154]: %timeit df.groupby(['g1', 'g2', 'g3'], sort=False).sum()                            
    4.13 s ± 823 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
  • Мне все равно, сгруппирован ли конечный результат (g3 , g1, g2) или (g1, g2, g3).

  • Может быть, я просто предполагаю, что сортировка не то, что на самом деле здесь требуется время, это сама агрегация.

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