kagglePandas分组和排序
Introduction
映射允许我们一次转换 DataFrame 或 Series 中整列的数据,每次转换一个值。然而,我们通常希望对数据进行分组,然后针对数据所在的组执行特定操作。
正如您将了解到的,我们使用 groupby() 操作来实现这一点。我们还将介绍一些其他主题,例如更复杂的 DataFrame 索引方法以及如何对数据进行排序。
要开始此主题的练习,请点击此处。
Groupwise analysis
到目前为止,我们经常使用的一个函数是“value_counts()”函数。我们可以通过执行以下操作来复制“value_counts()”的功能:
import pandas as pd |
In [2]:
reviews.groupby('points').points.count() |
Out[2]:
points |
groupby() 创建了一组评论,这些评论为给定的葡萄酒分配了相同的分值。然后,对于每个组,我们获取 points() 列并计算其出现的次数。value_counts() 只是 groupby() 操作的快捷方式。
我们可以将之前使用过的任何汇总函数用于这些数据。例如,要获取每个分值类别中最便宜的葡萄酒,我们可以执行以下操作:
In [3]:
reviews.groupby('points').price.min() |
Out[3]:
points |
您可以将我们生成的每个组视为 DataFrame 的一个切片,其中仅包含值匹配的数据。我们可以使用 apply() 方法直接访问此 DataFrame,然后以任何我们认为合适的方式操作数据。例如,以下是从数据集中每个酒庄中抽取第一款被评论的葡萄酒名称的一种方法:
In [4]:
reviews.groupby('winery').apply(lambda df: df.title.iloc[0]) |
Out[4]:
winery |
为了实现更精细的控制,您还可以按多列进行分组。例如,以下是按国家和省份挑选最佳葡萄酒的方法:
In [5]:
reviews.groupby(['country', 'province']).apply(lambda df: df.loc[df.points.idxmax()]) |
Out[5]:
| country | description | designation | points | price | province | region_1 | region_2 | taster_name | taster_twitter_handle | title | variety | winery | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| country | province | |||||||||||||
| Argentina | Mendoza Province | Argentina | If the color doesn’t tell the full story, the … | Nicasia Vineyard | 97 | 120.0 | Mendoza Province | Mendoza | NaN | Michael Schachner | @wineschach | Bodega Catena Zapata 2006 Nicasia Vineyard Mal… | Malbec | Bodega Catena Zapata |
| Other | Argentina | Take note, this could be the best wine Colomé … | Reserva | 95 | 90.0 | Other | Salta | NaN | Michael Schachner | @wineschach | Colomé 2010 Reserva Malbec (Salta) | Malbec | Colomé | |
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
| Uruguay | San Jose | Uruguay | Baked, sweet, heavy aromas turn earthy with ti… | El Preciado Gran Reserva | 87 | 50.0 | San Jose | NaN | NaN | Michael Schachner | @wineschach | Castillo Viejo 2005 El Preciado Gran Reserva R… | Red Blend | Castillo Viejo |
| Uruguay | Uruguay | Cherry and berry aromas are ripe, healthy and … | Blend 002 Limited Edition | 91 | 22.0 | Uruguay | NaN | NaN | Michael Schachner | @wineschach | Narbona NV Blend 002 Limited Edition Tannat-Ca… | Tannat-Cabernet Franc | Narbona |
425 行 × 13 列
另一个值得一提的 groupby() 方法是 agg(),它允许你同时在 DataFrame 上运行多个不同的函数。例如,我们可以生成一个简单的数据集统计摘要,如下所示:
In [6]:
reviews.groupby(['country']).price.agg([len, min, max]) |
Out[6]:
| len | min | max | |
|---|---|---|---|
| country | |||
| Argentina | 3800 | 4.0 | 230.0 |
| Armenia | 2 | 14.0 | 15.0 |
| … | … | … | … |
| Ukraine | 14 | 6.0 | 13.0 |
| Uruguay | 109 | 10.0 | 130.0 |
43 行 × 3 列
有效使用 groupby() 可以让你对数据集进行许多非常强大的操作。
Multi-indexes
到目前为止,我们看到的所有示例中,我们处理的都是具有单标签索引的 DataFrame 或 Series 对象。groupby() 略有不同,根据我们运行的操作,它有时会导致所谓的多重索引。
多重索引与常规索引的不同之处在于它具有多个级别。例如:
In [7]:
countries_reviewed = reviews.groupby(['country', 'province']).description.agg([len]) |
Out[7]:
| len | ||
|---|---|---|
| country | province | |
| Argentina | Mendoza Province | 3264 |
| Other | 536 | |
| … | … | … |
| Uruguay | San Jose | 3 |
| Uruguay | 24 |
425行×1列
In [8]:
mi = countries_reviewed.index |
Out[8]:
pandas.core.indexes.multi.MultiIndex |
多索引有几种处理其分层结构的方法,而单级索引则没有。它们还需要两级标签来检索值。处理多索引输出是 Pandas 新用户常见的“陷阱”。
多索引的用例及其使用说明在 Pandas 文档的 多索引 / 高级选择 部分中有详细说明。
不过,通常情况下,您最常使用的多索引方法是用于转换回常规索引的方法,即 reset_index() 方法:
In [9]:
countries_reviewed.reset_index() |
Out[9]:
| country | province | len | |
|---|---|---|---|
| 0 | Argentina | Mendoza Province | 3264 |
| 1 | Argentina | Other | 536 |
| … | … | … | … |
| 423 | Uruguay | San Jose | 3 |
| 424 | Uruguay | Uruguay | 24 |
425行×3列
Sorting
再次查看 countries_reviewed,我们可以看到分组返回的数据是按索引顺序排列的,而不是按值顺序排列的。也就是说,输出 groupby 的结果时,行的顺序取决于索引中的值,而不是数据中的值。
为了按所需的顺序获取数据,我们可以自行排序。sort_values() 方法非常方便。
In [10]:
countries_reviewed = countries_reviewed.reset_index() |
Out[10]:
| country | province | len | |
|---|---|---|---|
| 179 | Greece | Muscat of Kefallonian | 1 |
| 192 | Greece | Sterea Ellada | 1 |
| … | … | … | … |
| 415 | US | Washington | 8639 |
| 392 | US | California | 36247 |
425 行 × 3 列
sort_values() 默认按升序排序,即最小值优先。然而,大多数情况下,我们希望按降序排序,即数值较大的值优先。具体如下:
In [11]:
countries_reviewed.sort_values(by='len', ascending=False) |
Out[11]:
| country | province | len | |
|---|---|---|---|
| 392 | US | California | 36247 |
| 415 | US | Washington | 8639 |
| … | … | … | … |
| 63 | Chile | Coelemu | 1 |
| 149 | Greece | Beotia | 1 |
425 行 × 3 列
要按索引值排序,请使用配套方法 sort_index()。此方法具有相同的参数和默认顺序:
In [12]:
countries_reviewed.sort_index() |
Out[12]:
| country | province | len | |
|---|---|---|---|
| 0 | Argentina | Mendoza Province | 3264 |
| 1 | Argentina | Other | 536 |
| … | … | … | … |
| 423 | Uruguay | San Jose | 3 |
| 424 | Uruguay | Uruguay | 24 |
425 行 × 3 列
最后,请注意,您可以同时按多列排序:
In [13]:
countries_reviewed.sort_values(by=['country', 'len']) |
Out[13]:
| country | province | len | |
|---|---|---|---|
| 1 | Argentina | Other | 536 |
| 0 | Argentina | Mendoza Province | 3264 |
| … | … | … | … |
| 424 | Uruguay | Uruguay | 24 |
| 419 | Uruguay | Canelones | 43 |
425行×3列
Your turn
如果你还没有开始练习,你可以**从这里开始**。
