Chapter 08
数据处理:Python 与 Pandas 库
数据处理:Python 与 Pandas 库
![]() |
|---|
| 使用 Python - 由 @nitya 制作的速写笔记 |
虽然数据库提供了非常高效的存储数据和使用查询语言查询数据的方式,但数据处理最灵活的方式是编写自己的程序来操作数据。在许多情况下,执行数据库查询会更有效。然而,有些情况需要更复杂的数据处理,使用 SQL 很难实现。
数据处理可以用任何编程语言来编写,不过有些语言在处理数据方面有更高级的表现。数据科学家通常偏好以下几种语言:
- Python,一种通用编程语言,通常因其简洁性被视为初学者的最佳选择之一。Python 拥有大量额外库,可以帮助解决许多实际问题,比如从 ZIP 压缩包中提取数据,或将图片转换为灰度图。除了数据科学之外,Python 也常用于网页开发。
- R 是一个传统的工具箱,专门为统计数据处理开发。它还包含大型库仓库(CRAN),是进行数据处理的不错选择。然而,R 不是通用编程语言,在数据科学领域外很少使用。
- Julia 是另一种专为数据科学开发的语言。它旨在比 Python 提供更好的性能,是科学实验的优秀工具。
本课将重点介绍使用 Python 进行简单数据处理。我们假设你对该语言有基本了解。如果你想更深入学习 Python,可以参考以下资源:
- 用 Turtle 图形和分形有趣地学习 Python - GitHub 上的 Python 编程快速入门课程
- 迈出 Python 的第一步,微软学习平台上的学习路径
数据可以有多种形式。本课将考虑三种数据形式——表格数据、文本 和 图像。
我们将重点介绍几种数据处理示例,而不是详尽介绍所有相关库。这有助于你掌握主要思想,并让你了解在需要时去哪里寻找解决方案。
最有用的建议。当你需要对数据执行某种操作但不知道如何操作时,试着在网上搜索。Stackoverflow 通常包含很多关于典型任务的 Python 代码示例。
课前测验
表格数据与数据框
当我们谈论关系型数据库时,你已经接触过表格数据。若数据量很大且包含多个相互关联的表,使用 SQL 处理数据显然更合适。不过,很多情况下仅有一张数据表,我们需要对数据获得一些理解或洞见,比如分布情况、值之间的相关性等。在数据科学中,常常需要对原始数据做一些变换,然后进行可视化。上述步骤都可以用 Python 轻松完成。
Python 中有两个非常有用的库可以帮助你处理表格数据:
- Pandas 支持操作所谓的 数据框(Dataframes),类似关系型表。你可以有命名列,并对行、列以及整体数据框执行各种操作。
- Numpy 是用于处理 张量,即多维 数组 的库。数组内元素类型相同,结构比数据框简单,但提供更多数学运算,且占用开销更小。
另外还有几个你应该了解的库:
- Matplotlib 用于数据可视化和绘图
- SciPy 附加科学计算功能的库。我们在讲概率和统计时已经遇到过它
下面这段代码是你通常在 Python 程序开头导入上述库的写法:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import ... # 你需要指定你需要的确切子包Pandas 围绕几个基本概念展开。
序列(Series)
Series 是值的序列,类似列表或 numpy 数组。主要区别是序列还有一个索引,操作序列时(如相加)会考虑索引。索引可以是简单的整数行号(当从列表或数组创建序列时默认索引),也可以是复杂结构,比如日期区间。
注:伴随教材中有一些基础 Pandas 代码,见
notebook.ipynb。这里仅列举部分示例,你可以查看完整笔记本。
举个例子:我们想分析冰淇淋店的销售额。生成一个销售数量序列(每天售出数量)如下:
start_date = "Jan 1, 2020"
end_date = "Mar 31, 2020"
idx = pd.date_range(start_date,end_date)
print(f"Length of index is {len(idx)}")
items_sold = pd.Series(np.random.randint(25,50,size=len(idx)),index=idx)
items_sold.plot()
假设每周我们为朋友举办派对,额外准备 10 包冰淇淋。可以创建另一个以周为索引的序列表示:
additional_items = pd.Series(10,index=pd.date_range(start_date,end_date,freq="W"))把两个序列相加,得到总数:
total_items = items_sold.add(additional_items,fill_value=0)
total_items.plot()
注意,这里没有使用简单写法
total_items+additional_items。若用简单写法,会得到很多NaN(非数字)值。因为additional_items序列在某些索引处缺失值,而任何数加NaN仍为NaN。所以相加时要指定fill_value参数。
对时间序列,还可以用不同时间间隔进行重采样。例如要计算月均销售量,可以用以下代码:
monthly = total_items.resample("1M").mean()
ax = monthly.plot(kind='bar')
数据框(DataFrame)
数据框本质上是同一索引的多个序列集合。我们可以把几个序列合并为一个数据框:
a = pd.Series(range(1,10))
b = pd.Series(["I","like","to","play","games","and","will","not","change"],index=range(0,9))
df = pd.DataFrame([a,b])这会创建如下横向表格:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 1 | I | like | to | use | Python | and | Pandas | very | much |
也可以用序列作为列,通过字典指定列名:
df = pd.DataFrame({ 'A' : a, 'B' : b })生成如下表格:
| A | B | |
|---|---|---|
| 0 | 1 | I |
| 1 | 2 | like |
| 2 | 3 | to |
| 3 | 4 | use |
| 4 | 5 | Python |
| 5 | 6 | and |
| 6 | 7 | Pandas |
| 7 | 8 | very |
| 8 | 9 | much |
注意也可以通过转置上表得到这种布局,例如写成
df = pd.DataFrame([a,b]).T.rename(columns={ 0 : 'A', 1 : 'B' })这里 .T 表示转置操作,即行列转换,rename 操作用于重命名列使其匹配上述示例。
以下是我们常用的数据框操作:
选列。用 df['A'] 选择单列返回序列。用 df 选择多列返回数据框。
按条件过滤行。例如保留列 A 大于 5 的行,可以写 df[df['A']>5]。
注意:过滤通过布尔序列实现。表达式
df['A']<5返回布尔序列表示每个元素是否满足条件,布尔序列用作索引返回满足条件的行。不能使用普通布尔表达式,比如df[df['A']>5 and df['A']<7]是错误的。应使用专用的&运算符,写成df[(df['A']>5) & (df['A']<7)](括号很重要)。
创建可计算新列。可以用直观表达式轻松创建新列:
df['DivA'] = df['A']-df['A'].mean() 示例中计算了列 A 与其均值的差值。实际上是先计算出一个序列,然后赋值为新列。故不能用不支持序列的操作,例如,下面代码是错误写法:
# 错误的代码 -> df['ADescr'] = "Low" if df['A'] < 5 else "Hi"
df['LenB'] = len(df['B']) # <- 错误的结果该例语法正确,但返回错误结果,因为它将序列 B 的长度赋给所有单元格,而不是每个元素的长度。
若计算复杂表达式,可用 apply 函数。上述例子可写成:
df['LenB'] = df['B'].apply(lambda x : len(x))
# 或者
df['LenB'] = df['B'].apply(len)经过上述操作,我们将得到如下数据框:
| A | B | DivA | LenB | |
|---|---|---|---|---|
| 0 | 1 | I | -4.0 | 1 |
| 1 | 2 | like | -3.0 | 4 |
| 2 | 3 | to | -2.0 | 2 |
| 3 | 4 | use | -1.0 | 3 |
| 4 | 5 | Python | 0.0 | 6 |
| 5 | 6 | and | 1.0 | 3 |
| 6 | 7 | Pandas | 2.0 | 6 |
| 7 | 8 | very | 3.0 | 4 |
| 8 | 9 | much | 4.0 | 4 |
基于行号选择行,可用 iloc。比如选择前5行:
df.iloc[:5]分组常用于实现类似 Excel 数据透视表的功能。假设想对每个 LenB 值计算列 A 的均值,可以用 LenB 分组,再调用 mean:
df.groupby(by='LenB').mean()如果要计算均值和组内元素数量,可用更复杂的 aggregate 函数:
df.groupby(by='LenB') \
.aggregate({ 'DivA' : len, 'A' : lambda x: x.mean() }) \
.rename(columns={ 'DivA' : 'Count', 'A' : 'Mean'})得到如下表:
| LenB | Count | Mean |
|---|---|---|
| 1 | 1 | 1.000000 |
| 2 | 1 | 3.000000 |
| 3 | 2 | 5.000000 |
| 4 | 3 | 6.333333 |
| 6 | 2 | 6.000000 |
获取数据
我们已经看到,从Python对象构建Series和DataFrame是多么简单。然而,数据通常以文本文件或Excel表格的形式出现。幸运的是,Pandas为我们提供了一种简便的方法从磁盘加载数据。例如,读取CSV文件就像这样简单:
df = pd.read_csv('file.csv')我们将在“挑战”部分看到更多加载数据的例子,包括从外部网站抓取数据
打印和绘图
数据科学家经常需要探索数据,因此能够将其可视化非常重要。当DataFrame很大时,很多时候我们只想通过打印前几行来确认一切操作正确。这可以通过调用df.head()来完成。如果你在Jupyter Notebook中运行,它会以漂亮的表格形式打印DataFrame。
我们还见过使用plot函数来可视化某些列。虽然plot对许多任务非常有用,并且通过kind=参数支持多种图形类型,你也可以使用原生的matplotlib库绘制更复杂的图形。我们将在其他课程详细讲解数据可视化。
本概述涵盖了Pandas的大部分重要概念,然而,这个库功能丰富,你可以用它做的事情没有限制!现在让我们用这些知识解决具体问题。
🚀 挑战1:分析COVID传播
我们首先关注的问题是COVID-19流行病传播建模。为此,我们将使用约翰霍普金斯大学(Johns Hopkins University)系统科学与工程中心(CSSE)提供的不同国家感染人数数据。数据集可在此GitHub仓库找到。
由于我们想展示如何处理数据,邀请你打开notebook-covidspread.ipynb从头到尾阅读。你也可以执行代码单元,并完成我们在最后留下的挑战。

如果你不知道如何在Jupyter Notebook中运行代码,请查看这篇文章。
处理非结构化数据
虽然数据经常以表格形式出现,但有些情况下我们需要处理较少结构化的数据,例如文本或图像。此时,要应用之前看到的数据处理技术,我们需要以某种方式提取结构化数据。这里有几个例子:
- 从文本中提取关键词,并统计关键词出现的频率
- 使用神经网络提取图像中对象的信息
- 从视频摄像头画面中获取人物情绪信息
🚀 挑战2:分析COVID论文
这次挑战我们将继续聚焦COVID疫情主题,处理相关科学论文。CORD-19数据集(CORD-19 Dataset)含有超过7000篇(撰写时)关于COVID的论文,提供元数据和摘要(大约一半论文也提供了全文)。
使用Text Analytics for Health认知服务分析该数据集的完整示例,见这篇博客文章。我们将讨论此分析的简化版本。
注意:我们不提供数据集副本作为本仓库的一部分。你首先可能需要从Kaggle上的数据集下载
metadata.csv文件。使用Kaggle可能需要注册。你也可以从这里下载数据集(无需注册),但会包含全文和元数据文件。
打开notebook-papers.ipynb从头到尾阅读。你也可以执行代码单元,并完成我们在最后留下的挑战。

处理图像数据
最近,开发了非常强大的AI模型,使我们能够理解图像。有许多任务可以使用预训练神经网络或云服务解决。例子包括:
- 图像分类,可以帮助你将图像归类到预定义类别之一。你可以使用如Custom Vision等服务轻松训练自己的图像分类器
- 物体检测,检测图像中的不同物体。像计算机视觉服务能够检测许多常见物体,你也可以训练Custom Vision模型来检测特定感兴趣物体。
- 人脸检测,包括年龄、性别和情绪检测。可以通过Face API完成。
所有这些云服务都可以通过Python SDK调用,从而轻松融入数据探索工作流。
这里有一些使用图像数据源探索数据的例子:
- 在博客文章如何无代码学习数据科学中,我们探索Instagram照片,尝试理解什么因素令照片获得更多点赞。我们首先使用计算机视觉提取尽可能多的图像信息,然后使用Azure机器学习AutoML构建可解释模型。
- 在面部研究工作坊中,我们使用Face API提取活动照片中人物的情绪,以尝试理解什么让人快乐。
结论
无论你已经拥有结构化还是非结构化数据,使用Python你都可以完成所有与数据处理和理解相关的步骤。这可能是数据处理最灵活的方式,这也是为何大多数数据科学家将Python作为主要工具的原因。如果你认真对待数据科学之路,深入学习Python是个好主意!
课后测验
复习与自学
书籍
在线资源
学习Python
作业
致谢
本课由Dmitry Soshnikov满载 ♥️ 撰写
免责声明: 本文件由 AI 翻译服务 Co-op Translator 翻译完成。尽管我们力求准确,但请注意,自动翻译可能包含错误或不准确之处。原始语言版文件应视为权威来源。对于重要信息,建议使用专业人工翻译。我们对因使用本翻译而产生的任何误解或误释不承担责任。


