2016-10-27 12 views
1

私が作業しているデータセットはhereです。 Chipotleの注文データです。アイテムの種類ごとにitem_nameがあり、item_nameの中には、アイテム内に正確に何が入っているかを複数記述することができます。パンダ:特定の列のgroupby内でソート

それでは、最初のファイルをインポートし、少しそれをクリーンアップしてみましょう:

chipo = pd.read_csv('chipotle.tsv', sep='\t') 
del chipo['order_id'] 
del chipo['quantity'] 
chipo['revenue'] = chipo['item_price'].str.replace('$','').astype(float) 
chipo['count'] = 1 

私はチームitem_nameごとに発注されるどのように多くの各choice_descriptionの集計しようとしています。これは、

grouped = chipo.groupby(['item_name','choice_description']).sum() 

GROUPBYを使用して、(ものの列を含む)の列を合計することにより、十分に簡単ですが、今、私はソート'item_name'内のカウントにしたいです。ああ、後で計算できるようにitem_priceの列を保持したいので、DataFrameを1列のフレームに変換するだけではできません。私の人生のために、私はこれを行う方法を理解することはできません。

grouped.sort_values('count')は、item_nameグループ内だけでなく、すべての観測で並べ替えることができます。その列で並べ替えるだけで、グループ内で並べ替えを制限することはできますか?それらのすべて廃止予定のソートコマンドを使用します(例えばSeries.order()またはDataFrame.sort())または私が必要まさに行わないのどちらかが、(例えばhere)これを議論する以前の回答にあるようですにもかかわらず

。この一見単純な作業をどうすればできますか?

答えて

2

どのように私はちょうど並べ替え、その列ではなく、グループ内に拘束ソートを保つことができますか?

両方で並べ替えます。item_namecountitem_nameはインデックスレベルで、countは列ですので、item_nameを列に移動してDataFrame.sort_valuesに電話するか、またはcountをインデックスに移動してDataFrame.sortlevelに電話する必要があります。例えば

import pandas as pd 
chipo = pd.read_csv('chipotle.tsv', sep='\t') 
del chipo['order_id'] 
del chipo['quantity'] 
chipo['revenue'] = chipo['item_price'].str.replace('$','').astype(float) 
chipo['count'] = 1 
result = chipo.groupby(['item_name','choice_description']).sum() 

result = (result.set_index('count', append=True) 
      .sortlevel(axis=0, level=['item_name', 'count'], ascending=False) 
      .reset_index('count', drop=False)) 

について

sortlevelsort_valuesより少し速い用いて、上記の二つのオプションの

                  revenue \ 
                     revenue count 
item_name    choice_description             
Veggie Salad Bowl  [Fresh Tomato Salsa, [Fajita Vegetables, Lettuc... 11.25  1 
         [Fresh Tomato Salsa, [Fajita Vegetables, Rice, ... 11.25  1 
         [Fresh Tomato Salsa, [Fajita Vegetables, Rice, ... 11.25  1 
         [Fresh Tomato Salsa, [Rice, Lettuce, Guacamole,... 11.25  1 
...      
Barbacoa Bowl   [Roasted Chili Corn Salsa, [Fajita Vegetables, ... 23.50  2 
         [Fresh Tomato Salsa, [Fajita Vegetables, Rice, ...  9.25  1 
         [Fresh Tomato Salsa, [Fajita Vegetables, Rice, ...  9.25  1 
         [Tomatillo Red Chili Salsa, [Fajita Vegetables,... 11.75  1 
         [Tomatillo Red Chili Salsa, [Rice, Black Beans,...  9.25  1 
         [Tomatillo Red Chili Salsa, [Rice, Cheese, Lett...  9.25  1 
         [Tomatillo Red Chili Salsa, [Rice, Pinto Beans,...  9.25  1 
         [[Tomatillo-Green Chili Salsa (Medium), Roasted... 11.48  1 
         [[Tomatillo-Red Chili Salsa (Hot), Tomatillo-Gr...  8.99  1 
6 Pack Soft Drink  [Diet Coke]           19.47  3 
         [Coke]             6.49  1 
         [Sprite]            6.49  1 

[314 rows x 2 columns] 

をもたらします。

In [73]: %timeit using_sortlevel(totals) 
10 loops, best of 3: 148 ms per loop 

In [74]: %timeit using_sort_values(totals) 
10 loops, best of 3: 174 ms per loop 

この設定を使用して::

import pandas as pd 
N = 10**6 
chipo = pd.DataFrame(np.random.randint(1000, size=(N,4)), columns=list('ABCD')) 
totals = chipo.groupby(['A','B']).sum() 

def using_sortlevel(df): 
    return (df.set_index('C', append=True) 
      .sortlevel(axis=0, level=['A', 'C'], ascending=False) 
      .reset_index('C', drop=False)) 

def using_sort_values(df): 
    return (df.reset_index('A') 
      .sort_values(by=['A', 'C'], ascending=False) 
      .set_index('A', append=True) 
      .swaplevel(0, 1, axis=0)) 
+0

興味深い はここでベンチマークです。私はこれを行うためのより「組み込みの」方法があると考えていたでしょう(これはやりにくいことではありません)。ありがとう。 – gogurt