11

グループ化に従って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"]})

とでグループ化するgroup1group2、各グループの行数は次のようになります。

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    

(それを計算するさらに簡潔な方法がある場合は、教えてください。)

次に、各グループからランダムに選択された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

動作します。ただし、実際のデータには約250万行と12列があります。独自のデータ構造を構築してこれを汚い方法で行うと、この操作を数秒で完了できます。ただし、上記の実装は30分以内に完了しません(メモリが制限されているようには見えません)。ちなみに、これをRで実装しようとしたとき、最初に試しplyrましたが、これも妥当な時間で終了しませんでした。ただし、を使用したソリューションdata.tableは非常に迅速に終了しました。

これを迅速に機能させるにはどうすればよいpandasですか?このパッケージが大好きなので、助けてください!

4

1 に答える 1

8

applyでテストしましたが、サブグループが多いと非常に遅いようです。groupedのgroups属性はdictであり、そこから直接インデックスを選択できます。

subsampled = df.ix[(choice(x) for x in grouped.groups.itervalues())]

編集:パンダバージョン0.18.1以降、itervaluesgroupbyオブジェクトでは機能しなくなりました-次を使用できます.values

subsampled = df.ix[(choice(x) for x in grouped.groups.values())]
于 2011-09-28T08:35:50.070 に答える