pandas指南-4.数据分组聚合和排序
目录
数据分组聚合和排序
分组聚合非常重要,它在官方pandas文档中有自己的部分:Groupby:split-apply-combine。
import pandas as pd
pd.set_option('max_rows', 5)
import numpy as np
melbourne_data = pd.read_csv('melb_data.csv')
melbourne_data.head()
映射map允许我们一次为整个列转换DataFrame或Series中的数据。 但是,我们通常希望对数据进行分组,然后对数据所在的组执行特定操作。为此,我们可以使用groupby操作。
例如,到目前为止我们一直在大量使用的函数是value_counts函数。 我们可以通过执行以下groupby操作来复制value_counts执行的操作:
melbourne_data.groupby('Rooms').Rooms.count()
Rooms
1 681
2 3648
...
8 8
10 1
Name: Rooms, Length: 9, dtype: int64
groupby创建了一组分类,为给定的房屋分类分配相同的点值。 然后,对于这些组中的每一组,我们计算它出现的次数。
value_counts只是此groupby操作的快捷方式。 我们可以使用我们之前使用过的任何汇总函数。 例如,要获得每个类别中最便宜的房屋,我们可以执行以下操作:
melbourne_data.groupby('Rooms').Price.min()
Rooms
1 85000.0
2 190000.0
...
8 741000.0
10 900000.0
Name: Price, Length: 9, dtype: float64
你可以将我们生成的每个组视为我们的DataFrame的一个片段,其中仅包含值匹配的数据。 我们可以使用apply方法直接访问此DataFrame,然后我们可以以我们认为合适的任何方式操作数据。 例如,这里有一种方法可以选择数据集中每个房屋郊县的第一个房屋的地址:
melbourne_data.groupby('Suburb').apply(lambda df: df.Address.iloc[0])
Suburb
Abbotsford 85 Turner St
Aberfeldie 2/2 St Kinnord St
...
Yarra Glen 15 Yarra St
Yarraville 13 Benbow St
Length: 314, dtype: object
对于更细粒度的控制,你还可以按多个列进行分组。 举个例子,我们将按区域Region和郊县Suburb挑选贵的房屋:
melbourne_data.groupby(['Regionname', 'Suburb']).apply(lambda df: df.loc[df.Price.idxmax()])
另一个值得一提的groupby方法是agg,它允许你同时在DataFrame上运行一堆不同的函数。 例如,我们可以生成数据集的简单统计摘要,如下所示
melbourne_data.groupby(['Suburb']).Price.agg([len, min, max])
有效使用groupby将允许你使用数据集执行许多非常强大的操作。(这里的len其实就是求分组后 每个组的记录数目)
多索引
在我们迄今为止看到的所有示例中,我们一直在使用具有单标签索引的DataFrame或Series对象。 groupby略有不同,因为根据我们运行的操作,它有时会产生所谓的多索引。
多索引与常规索引的不同之处在于它具有多个级别。 例如:
house = melbourne_data.groupby(['Regionname', 'Suburb']).Address.agg([len])
house
多索引有几种处理其分层结构的方法,这些方法对于单级索引是不存在的。 它还需要两个级别的标签来检索值。 处理多索引输出对于刚接触pandas的用户来说是一个常见的“问题”。
详细说明MultiIndex的用例以及在pandas文档的MultiIndex / Advanced Selection部分中使用它们的详细说明。
但是,通常你最常使用的MultiIndex方法是转换回常规索引的方法,即reset_index方法:
house.reset_index()
排序
再看看house,我们可以看到分组按索引顺序返回数据,而不是按值顺序返回。 也就是说,当输出groupby的结果时,行的顺序取决于索引中的值,而不是数据中的值。
为了获得我们想要的数据,我们可以自己对其进行排序。 sort_values方法对此非常方便。
house = house.reset_index()
house.sort_values(by='len')
sort_values默认为升序排序,其中最低值排在第一位。 大多数情况下,我们想要降序排序,其中较高的数字首先出现。 这样做:
house.sort_values(by='len', ascending=False)
要按索引值排序,请使用配套方法sort_index。 此方法具有相同的参数和默认顺序
house.sort_index()
最后,可以一次按多列排序:
house.sort_values(by=['Regionname', 'len'])