Как эффективно выполнить субдискретизацию большого DataFrame по группам с помощью pandas?

Я пытаюсь подвыборку строк DataFrame в соответствии с группировкой. Вот пример. Скажем, я определяю следующие данные:

from pandas import *
df = DataFrame({'group1' : ["a","b","a","a","b","c","c","c","c",
                            "c","a","a","a","b","b","b","b"],
                'group2' : [1,2,3,4,1,3,5,6,5,4,1,2,3,4,3,2,1],
                'value'  : ["apple","pear","orange","apple",
                            "banana","durian","lemon","lime",
                            "raspberry","durian","peach","nectarine",
                            "banana","lemon","guava","blackberry","grape"]})

Если я группирую по group1 и ] group2 , то количество строк в каждой группе находится здесь:

In [190]: df.groupby(['group1','group2'])['value'].agg({'count':len})
Out[190]: 
      count
a  1  2    
   2  1    
   3  2    
   4  1    
b  1  2    
   2  2    
   3  1    
   4  1    
c  3  1    
   4  1    
   5  2    
   6  1    

(Если есть еще более краткий способ вычисления, сообщите об этом.)

Теперь я хочу создать DataFrame, у которого есть один случайным образом выбранная строка из каждой группы. Мое предложение состоит в том, чтобы сделать это так:

In [215]: from random import choice
In [216]: grouped = df.groupby(['group1','group2'])
In [217]: subsampled = grouped.apply(lambda x: df.reindex(index=[choice(range(len(x)))]))
In [218]: subsampled.index = range(len(subsampled))
In [219]: subsampled
Out[219]: 
    group1  group2  value
0   b       2       pear 
1   a       1       apple
2   b       2       pear 
3   a       1       apple
4   a       1       apple
5   a       1       apple
6   a       1       apple
7   a       1       apple
8   a       1       apple
9   a       1       apple
10  a       1       apple
11  a       1       apple

, что работает. Однако мои реальные данные содержат около 2,5 миллионов строк и 12 столбцов. Если я сделаю это грязным способом, построив свои собственные структуры данных, Я могу завершить эту операцию за считанные секунды. Однако моя реализация выше не завершается в течение 30 минут (и, похоже, не ограничена памятью). В качестве примечания: когда я попытался реализовать это в R, я сначала попробовал plyr , который также не завершился по причине большое количество времени; однако решение с использованием data.table завершилось очень быстро.

Как мне заставить это работать быстро с пандами ? Я хочу полюбить этот пакет, поэтому, пожалуйста, помогите!

10
задан piRSquared 4 January 2017 в 20:17
поделиться