kagglePandas摘要函数和映射
Introduction
在上一篇教程中,我们学习了如何从 DataFrame 或 Series 中筛选出相关数据。正如我们在练习中所演示的那样,从数据表示中提取正确的数据对于完成工作至关重要。
然而,数据并非总是以我们想要的格式从内存中直接输出。有时,我们需要自行进行一些工作来重新格式化数据以适应当前任务。本教程将介绍我们可以对数据应用的不同操作,以使输入“恰到好处”。
要开始本主题的练习,请点击此处。
我们将使用《葡萄酒杂志》的数据进行演示。
import pandas as pd |
reviews |
Out[2]:
| country | description | designation | points | price | province | region_1 | region_2 | taster_name | taster_twitter_handle | title | variety | winery | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Italy | Aromas include tropical fruit, broom, brimston… | Vulkà Bianco | 87 | NaN | Sicily & Sardinia | Etna | NaN | Kerin O’Keefe | @kerinokeefe | Nicosia 2013 Vulkà Bianco (Etna) | White Blend | Nicosia |
| 1 | Portugal | This is ripe and fruity, a wine that is smooth… | Avidagos | 87 | 15.0 | Douro | NaN | NaN | Roger Voss | @vossroger | Quinta dos Avidagos 2011 Avidagos Red (Douro) | Portuguese Red | Quinta dos Avidagos |
| … | … | … | … | … | … | … | … | … | … | … | … | … | … |
| 129969 | France | A dry style of Pinot Gris, this is crisp with … | NaN | 90 | 32.0 | Alsace | Alsace | NaN | Roger Voss | @vossroger | Domaine Marcel Deiss 2012 Pinot Gris (Alsace) | Pinot Gris | Domaine Marcel Deiss |
| 129970 | France | Big, rich and off-dry, this is powered by inte… | Lieu-dit Harth Cuvée Caroline | 90 | 21.0 | Alsace | Alsace | NaN | Roger Voss | @vossroger | Domaine Schoffit 2012 Lieu-dit Harth Cuvée Car… | Gewürztraminer | Domaine Schoffit |
129971 行 × 13 列
Summary functions
Pandas 提供了许多简单的“摘要函数”(非官方名称),它们可以以某种有用的方式重构数据。例如,考虑 describe() 方法:
In [3]:
reviews.points.describe() |
Out[3]:
count 129971.000000 |
此方法生成给定列属性的高级摘要。它具有类型感知功能,这意味着其输出会根据输入的数据类型而变化。上面的输出仅适用于数值数据;对于字符串数据,我们得到的结果如下:
In [4]:
reviews.taster_name.describe() |
Out[4]:
count 103727 |
如果您想获取 DataFrame 或 Series 中某一列的某些简单的摘要统计信息,通常可以使用 pandas 函数来实现。
例如,要查看所分配分数的平均值(例如,一款平均评分的葡萄酒的评价如何),我们可以使用 mean() 函数:
In [5]:
reviews.points.mean() |
Out[5]:
88.44713820775404 |
要查看唯一值列表,我们可以使用“unique()”函数:
In [6]:
reviews.taster_name.unique() |
Out[6]:
array(['Kerin O’Keefe', 'Roger Voss', 'Paul Gregutt', |
要查看唯一值列表以及它们在数据集中出现的频率,我们可以使用“value_counts()”方法:
In [7]:
reviews.taster_name.value_counts() |
Out[7]:
Roger Voss 25514 |
Maps
map 是一个源自数学的术语,指将一组值“映射”到另一组值的函数。在数据科学中,我们经常需要根据现有数据创建新的表示,或者将数据从当前格式转换为我们期望的格式。map 就是处理这项工作的工具,因此它们对于完成工作至关重要!
有两种映射方法你会经常使用。
map() 是第一种,也稍微简单一些。例如,假设我们想将葡萄酒的得分重新平均为 0。我们可以这样做:
In [8]:
review_points_mean = reviews.points.mean() |
Out[8]:
0 -1.447138 |
传递给 map() 的函数应该从 Series 中获取一个值(在上例中是一个点值),并返回该值的转换版本。map() 返回一个新的 Series,其中所有值都已由你的函数转换。
如果我们想通过在每一行上调用自定义方法来转换整个 DataFrame,那么 apply() 是等效方法。
In [9]:
def remean_points(row): |
Out[9]:
| country | description | designation | points | price | province | region_1 | region_2 | taster_name | taster_twitter_handle | title | variety | winery | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Italy | Aromas include tropical fruit, broom, brimston… | Vulkà Bianco | -1.447138 | NaN | Sicily & Sardinia | Etna | NaN | Kerin O’Keefe | @kerinokeefe | Nicosia 2013 Vulkà Bianco (Etna) | White Blend | Nicosia |
| 1 | Portugal | This is ripe and fruity, a wine that is smooth… | Avidagos | -1.447138 | 15.0 | Douro | NaN | NaN | Roger Voss | @vossroger | Quinta dos Avidagos 2011 Avidagos Red (Douro) | Portuguese Red | Quinta dos Avidagos |
| … | … | … | … | … | … | … | … | … | … | … | … | … | … |
| 129969 | France | A dry style of Pinot Gris, this is crisp with … | NaN | 1.552862 | 32.0 | Alsace | Alsace | NaN | Roger Voss | @vossroger | Domaine Marcel Deiss 2012 Pinot Gris (Alsace) | Pinot Gris | Domaine Marcel Deiss |
| 129970 | France | Big, rich and off-dry, this is powered by inte… | Lieu-dit Harth Cuvée Caroline | 1.552862 | 21.0 | Alsace | Alsace | NaN | Roger Voss | @vossroger | Domaine Schoffit 2012 Lieu-dit Harth Cuvée Car… | Gewürztraminer | Domaine Schoffit |
129971 行 × 13 列
如果我们调用 reviews.apply() 时传入 `axis=’index’,那么我们就需要传入一个函数来转换每一行,而不是传入一个函数来转换每一列。
需要注意的是,map() 和 apply() 分别返回转换后的新 Series 和 DataFrame。它们不会修改调用它们的原始数据。如果我们查看 reviews 的第一行,就会发现它仍然保留着原来的 points 值。
In [10]:
reviews.head(1) |
Out[10]:
| country | description | designation | points | price | province | region_1 | region_2 | taster_name | taster_twitter_handle | title | variety | winery | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Italy | Aromas include tropical fruit, broom, brimston… | Vulkà Bianco | 87 | NaN | Sicily & Sardinia | Etna | NaN | Kerin O’Keefe | @kerinokeefe | Nicosia 2013 Vulkà Bianco (Etna) | White Blend | Nicosia |
Pandas 内置了许多常见的映射操作。例如,下面是一种更快速地重新定义 points 列的方法:
In [11]:
review_points_mean = reviews.points.mean() |
Out[11]:
0 -1.447138 |
在这段代码中,我们在左侧的多个值(Series 中的所有内容)和右侧的单个值(平均值)之间执行运算。Pandas 会查看这个表达式,并计算出我们的意思是从数据集中的每个值中减去该平均值。
如果我们在等长的 Series 之间执行这些运算,Pandas 也能理解该怎么做。例如,合并数据集中的国家和地区信息的一种简单方法是执行以下操作:
In [12]:
reviews.country + " - " + reviews.region_1 |
Out[12]:
0 Italy - Etna |
这些运算符比 map() 或 apply() 更快,因为它们使用了 Pandas 内置的加速功能。所有标准 Python 运算符(>、<、== 等)都以这种方式工作。
然而,它们不如 map() 或 apply() 灵活,后者可以执行更高级的操作,例如应用条件逻辑,而这仅靠加法和减法是无法实现的。
Your turn
如果你还没有开始练习,你可以**从这里开始**。
