蟒蛇pandas
包用于数据操作和分析,旨在让您以直观的方式处理标记数据或关系数据。
The pandas
软件包提供了电子表格功能,但由于您使用的是 Python,因此它比传统的图形电子表格程序更快、更高效。
在本教程中,我们将介绍如何设置一个大型数据集来使用,groupby()
and pivot_table()
的功能pandas
,最后是如何可视化数据。
为了熟悉pandas
包,你可以阅读我们的教程Python 3 中的 pandas 包及其数据结构简介.
本指南将介绍如何使用数据pandas
在本地桌面或远程服务器上。处理大型数据集可能会占用大量内存,因此无论哪种情况,计算机至少需要2GB内存执行本指南中的一些计算。
在本教程中,我们将使用Jupyter笔记本处理数据。如果您还没有,您应该遵循我们的安装和设置适用于 Python 3 的 Jupyter Notebook 的教程.
在本教程中,我们将使用有关婴儿姓名的美国社会保障数据,这些数据可从社会保障网站作为 8MB 的 zip 文件。
让我们在我们的电脑上激活 Python 3 编程环境本地机器,或者在我们的 server从正确的目录:
-
cd environments
-
. my_env/bin/activate
Now let’s create a new directory for our project. We can call it names
and then move into the directory:
-
mkdir names
-
cd names
在此目录中,我们可以使用以下命令从社会保障网站提取 zip 文件curl
命令:
-
curl -Ohttps://www.ssa.gov/oact/babynames/names.zip
下载文件后,让我们验证是否已安装将要使用的所有软件包:
-
numpy
支持多维数组
-
matplotlib
可视化数据
-
pandas
用于我们的数据分析
-
seaborn
让我们的matplotlib统计图形更加美观
如果您还没有安装任何软件包,请使用以下命令安装它们pip
, as in:
- pip install pandas
- pip install绘图库
- pip install西博恩
The numpy
如果您还没有安装包,也会安装它。
现在我们可以启动 Jupyter Notebook:
- Jupyter笔记本
进入 Jupyter Notebook 的 Web 界面后,您将看到names.zip
文件在那里。
要创建新的笔记本文件,请选择New > Python 3从右上角的下拉菜单中:
这将打开一个笔记本。
让我们从输入我们将使用的包。在笔记本的顶部,我们应该写下以下内容:
import numpy as np
import matplotlib.pyplot as pp
import pandas as pd
import seaborn
我们可以运行此代码并通过键入进入新的代码块ALT + ENTER
.
我们还告诉 Python Notebook 保持图表内联:
matplotlib inline
让我们运行代码并继续输入ALT + ENTER
.
从这里开始,我们将继续解压缩 zip 存档,将 CSV 数据集加载到pandas
,然后连接pandas
数据框.
要将 zip 存档解压缩到当前目录,我们将导入zipfile
模块,然后调用ZipFile
带有文件名的函数(在我们的例子中names.zip
):
import zipfile
zipfile.ZipFile('names.zip').extractall('.')
我们可以运行代码并继续输入ALT + ENTER
.
Now if you look back into your names
directory, you’ll have .txt
files of name data in CSV format. These files will correspond with the years of data on file, 1881 through 2015. Each of these files follow a similar naming convention. The 2015 file, for example, is called yob2015.txt
, while the 1927 file is called yob1927.txt
.
要查看其中一个文件的格式,让我们使用 Python 打开一个文件并显示前 5 行:
open('yob2015.txt','r').readlines()[:5]
运行代码并继续ALT + ENTER
.
Output
['Emma,F,20355\n',
'Olivia,F,19553\n',
'Sophia,F,17327\n',
'Ava,F,16286\n',
'Isabella,F,15504\n']
数据格式化的方式是名称优先(如Emma
or Olivia
),接下来是性行为(如F
对于女性名字和M
男性名字),然后是当年出生的以该名字命名的婴儿数量(2015 年出生的名为艾玛的婴儿有 20,355 名)。
有了这些信息,我们就可以将数据加载到pandas
.
将逗号分隔值数据加载到pandas
我们将使用pd.read_csv()
函数,传递文本文件的名称以及我们决定的列名称。在本例中,我们将其分配给一个变量names2015
因为我们使用的是 2015 年出生年份文件中的数据。
names2015 = pd.read_csv('yob2015.txt', names = ['Name', 'Sex', 'Babies'])
Type ALT + ENTER
运行代码并继续。
为了确保这一点成功,让我们显示表格的顶部:
names2015.head()
当我们运行代码并继续时ALT + ENTER
,我们将看到如下所示的输出:
我们的表现在包含按列排列的姓名、性别和出生婴儿数量的信息。
连接pandas
对象将允许我们处理所有单独的文本文件names
目录。
为了连接这些,我们首先需要通过将变量分配给未填充的列表来初始化列表列表数据类型:
all_years = []
完成后,我们将使用for loop按年份迭代所有文件,范围为 1880-2015。我们将添加+1
到 2015 年底,以便 2015 年包含在循环中。
all_years = []
for year in range(1880, 2015+1):
在循环中,我们将使用 a 将每个文本文件值附加到列表中字符串格式化程序处理每个文件的不同名称。我们将把这些值传递给year
多变的。同样,我们将指定列Name
, Sex
,以及数量Babies
:
all_years = []
for year in range(1880, 2015+1):
all_years.append(pd.read_csv('yob{}.txt'.format(year),
names = ['Name', 'Sex', 'Babies']))
此外,我们将为每年创建一个列以保持它们的顺序。我们可以在每次迭代后使用索引来做到这一点-1
随着循环的进行指向它们。
all_years = []
for year in range(1880, 2015+1):
all_years.append(pd.read_csv('yob{}.txt'.format(year),
names = ['Name', 'Sex', 'Babies']))
all_years[-1]['Year'] = year
最后,我们将其添加到pandas
使用连接的对象pd.concat()
功能。我们将使用变量all_names
来存储这些信息。
all_years = []
for year in range(1880, 2015+1):
all_years.append(pd.read_csv('yob{}.txt'.format(year),
names = ['Name', 'Sex', 'Babies']))
all_years[-1]['Year'] = year
all_names = pd.concat(all_years)
我们现在可以运行循环ALT + ENTER
,然后通过调用结果表的尾部(最底部的行)来检查输出:
all_names.tail()
我们的数据集现已完成,可以使用它进行额外的工作pandas
.
With pandas
您可以按列对数据进行分组.groupby()
功能。使用我们的all_names
我们的完整数据集的变量,我们可以使用groupby()
将数据拆分到不同的桶中。
让我们按性别和年份对数据集进行分组。我们可以这样设置:
group_name = all_names.groupby(['Sex', 'Year'])
我们可以运行代码并继续ALT + ENTER
.
此时如果我们只调用group_name
变量我们将得到这个输出:
Output
<pandas.core.groupby.DataFrameGroupBy object at 0x1187b82e8>
这向我们表明它是一个DataFrameGroupBy
目的。该对象具有有关如何对数据进行分组的说明,但没有给出有关如何显示值的说明。
为了显示值,我们需要给出指令。我们可以计算.size()
, .mean()
, and .sum()
,例如,返回一个表。
让我们从.size()
:
group_name.size()
当我们运行代码并继续时ALT + ENTER
,我们的输出将如下所示:
Output
Sex Year
F 1880 942
1881 938
1882 1028
1883 1054
1884 1172
...
该数据看起来不错,但还可以更具可读性。我们可以通过附加.unstack
功能:
group_name.size().unstack()
现在,当我们运行代码并继续输入时ALT + ENTER
,输出如下所示:
这些数据告诉我们的是每年有多少个女性和男性名字。例如,1889 年,女性名字有 1,479 个,男性名字有 1,111 个。 2015年,女性名字有18,993个,男性名字有13,959个。这表明随着时间的推移,名称出现了更大的多样性。
如果我们想要获得出生婴儿的总数,我们可以使用.sum()
功能。让我们将其应用到较小的数据集,names2015
从单个设置yob2015.txt
我们之前创建的文件:
names2015.groupby(['Sex']).sum()
让我们输入ALT + ENTER
运行代码并继续:
这向我们展示了 2015 年出生的男性和女性婴儿的总数,尽管数据集中只计算了该年名字被使用至少 5 次的婴儿。
The pandas
.groupby()
函数允许我们将数据分割成有意义的组。
数据透视表对于汇总数据很有用。它们可以自动对存储在一张表中的数据进行排序、计数、总计或平均。然后,他们可以在汇总数据的新表中显示这些操作的结果。
In pandas
, the pivot_table()
函数用于创建数据透视表。
要构建数据透视表,我们首先调用要使用的 DataFrame,然后调用要显示的数据以及它们的分组方式。
在此示例中,我们将使用all_names
数据,并在一个维度上按姓名分组,在另一个维度上按年份分组显示婴儿数据:
pd.pivot_table(all_names, 'Babies', 'Name', 'Year')
当我们打字时ALT + ENTER
运行代码并继续,我们将看到以下输出:
因为这显示了很多空值,所以我们可能希望将“名称”和“年份”保留为列,而不是在一种情况下保留为行,在另一种情况下保留为列。我们可以通过将数据分组在方括号中来做到这一点:
pd.pivot_table(all_names, 'Babies', ['Name', 'Year'])
一旦我们输入ALT + ENTER
要运行代码并继续,此表现在将仅显示每个名称记录的年份数据:
Output
Name Year
Aaban 2007 5.0
2009 6.0
2010 9.0
2011 11.0
2012 11.0
2013 14.0
2014 16.0
2015 15.0
Aabha 2011 7.0
2012 5.0
2014 9.0
2015 7.0
Aabid 2003 5.0
Aabriella 2008 5.0
2014 5.0
2015 5.0
此外,我们可以对数据进行分组,将姓名和性别作为一个维度,将年份作为另一个维度,如下所示:
pd.pivot_table(all_names, 'Babies', ['Name', 'Sex'], 'Year')
当我们运行代码并继续时ALT + ENTER
,我们会看到下表:
数据透视表让我们可以从现有表创建新表,从而使我们能够决定如何对数据进行分组。
通过使用pandas
与其他包一样matplotlib
我们可以在笔记本中可视化数据。
我们将可视化有关多年来某个名字的受欢迎程度的数据。为了做到这一点,我们需要设置和排序索引来重新处理数据,这将使我们能够看到特定名称的受欢迎程度的变化。
The pandas
包使我们能够执行分层或多级索引,从而使我们能够存储和操作具有任意维数的数据。
我们将使用性别信息、姓名信息、年份信息对数据进行索引。我们还想对索引进行排序:
all_names_index = all_names.set_index(['Sex','Name','Year']).sort_index()
Type ALT + ENTER
运行并继续到下一行,我们将让笔记本显示新的索引 DataFrame:
all_names_index
运行代码并继续ALT + ENTER
,输出将如下所示:
接下来,我们要编写一个函数来绘制某个名称随时间的流行程度。我们将调用该函数name_plot
并通过sex
and name
作为我们运行该函数时将调用的参数。
def name_plot(sex, name):
我们现在将设置一个名为data
来保存我们创建的表。我们还将使用pandas
数据框loc
为了通过索引的值选择我们的行。在我们的例子中,我们想要loc
基于 MultiIndex 中的字段组合,引用两个sex
and name
data.
让我们将这个结构写入我们的函数中:
def name_plot(sex, name):
data = all_names_index.loc[sex, name]
最后,我们想要绘制这些值matplotlib.pyplot
我们导入为pp
。然后,我们将根据索引绘制性别和姓名数据的值,对于我们的目的来说,索引是年。
def name_plot(sex, name):
data = all_names_index.loc[sex, name]
pp.plot(data.index, data.values)
Type ALT + ENTER
运行并移动到下一个单元格。我们现在可以使用我们选择的性别和名称来调用该函数,例如F
对于带有名字的女性名字Danica
.
name_plot('F', 'Danica')
当您输入时ALT + ENTER
现在,您将收到以下输出:
请注意,根据您使用的系统,您可能会收到有关字体替换的警告,但数据仍会正确绘制。
从可视化中我们可以看到,女性名字 Danica 在 1990 年左右的受欢迎程度略有上升,并在 2010 年之前达到顶峰。
我们创建的函数可用于绘制多个名称的数据,以便我们可以看到不同名称随时间变化的趋势。
让我们首先将绘图放大一点:
pp.figure(figsize = (18, 8))
接下来,让我们创建一个列表,其中包含我们要绘制的所有名称:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
现在,我们可以使用以下命令迭代列表for
循环并绘制每个名称的数据。首先,我们将尝试将这些中性名字作为女性名字:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
for name in names:
name_plot('F', name)
为了使这些数据更容易理解,我们添加一个图例:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
for name in names:
name_plot('F', name)
pp.legend(names)
我们将输入ALT + ENTER
运行代码并继续,然后我们将收到以下输出:
虽然每个名字作为女性名字都在慢慢流行,但 Jamie 这个名字在 1980 年左右作为女性名字最受欢迎。
让我们绘制相同的名字,但这次是男性名字:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
for name in names:
name_plot('M', name)
pp.legend(names)
再次输入ALT + ENTER
运行代码并继续。该图将如下所示:
该数据显示各种名字更受欢迎,Jesse 通常是最受欢迎的选择,并且在 20 世纪 80 年代和 90 年代尤其受欢迎。
从这里,您可以继续使用名称数据,创建有关不同名称及其受欢迎程度的可视化效果,并创建其他脚本来查看不同的数据以进行可视化。
本教程向您介绍了处理大型数据集的方法,从设置数据到对数据进行分组groupby()
and pivot_table()
,使用 MultiIndex 对数据进行索引,并可视化pandas
数据使用matplotlib
包裹。
许多组织和机构提供了数据集,您可以使用它们来继续了解pandas
和数据可视化。美国政府通过以下方式提供数据data.gov, 例如。
您可以了解有关可视化数据的更多信息matplotlib
遵循我们的指南如何使用 matplotlib 在 Python 3 中绘制数据 and 如何使用 matplotlib 和 Python 3 绘制词频图.