熊猫:在特定列的groupby中排序

时间:2016-10-27 22:57:05

标签: pandas

我正在使用的数据集是here。它是Chipotle订单的数据集。每种类型的商品都有item_name个商品,然后在item_name内有多个可能的choice_description来描述商品的确切内容。

所以,让我们先导入文件并稍微清理一下:

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

我试图将每个choice_description每个item_name的订单列表列表grouped = chipo.groupby(['item_name','choice_description']).sum() 。通过使用groupby然后对列进行求和(包括列的列),这很容易,

'item_name'

但现在我想item_price内的计数进行排序。哦,我还想保留grouped.sort_values('count')列,以便稍后进行计算,因此我可以'只需将DataFrame转换为单列框架即可。对于我的生活,我无法弄清楚如何做到这一点。

我无法致电item_name,因为它会对所有观察结果进行排序,而不仅仅是在Series.order()组内。我怎样才能按该列排序,但保持排序约束在组内?

即使之前的答案似乎在讨论这个问题(例如here),但所有这些答案都使用了弃用的排序命令(例如DataFrame.sort()或{{1}})或者不做正是我需要的。我怎样才能完成这个看似简单的任务?

1 个答案:

答案 0 :(得分:2)

  

如何按列排序,但保持排序限制在组内?

item_namecount排序。由于item_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))

产量

                                                                          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]

在上述两个选项中,使用sortlevelsort_values快一点。 这是一个基准:

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))