信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
引言
第1页
⚫ 数据清洗是进行大数据统计分析、机器学习、数据可视化的必要前提,数
据分析结果的好坏依赖于数据的质量。很多原始数据集存在数据缺失,或
数据格式不统一(畸形数据),或错误数据的情况。
⚫ 数据清洗是一项复杂且繁琐的工作,同时也是整个数据分析过程中最为重
要的环节。但在实际的工作中一个分析项目70%左右的时间花在清洗数据
上面。
⚫ 数据清洗的目的有两个:第一是通过清洗让数据可用;第二是让数据变得
更适合进行后续的分析工作。
⚫ NumPy库提供了方便的ndarray数组处理功能,而Pandas是基于NumPy开发
的含有更高级数据结构和工具的数据分析包,可以对各种数据进行运算操
作(例如归并、再成形、选择),广泛应用在学术、金融、统计学等各个
数据分析领域,同时它是数据清洗常用的工具。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Contents目录
01 Pandas中的数据对象
02 DataFrame的数据存取
03 数据读取与保存
04 操作DataFrame
06 删除指定数据和重复数据
07 数值运算方法
05 缺失值的处理
08 字符串数据处理
09 日期数据处理
10 数据清洗基本流程及示例
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Pandas中的数据对象
第3页
⚫ Pandas的主要数据结构是一维数据Series对象和二维数据DataFrame对象。
◼ Series对象是一种类似于一维数组的对象,它由一组数据(各种NumPy数据)以及一组
与之相关的数据标签索引组成。
◼ DataFrame对象是二维表格型的数据,它含有一组有序的列,每列可以是不同的值类型
(数值、字符串、布尔值、日期等)。DataFrame对象既有行索引也有列索引,它可以
被看作由Series组成的大字典。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第4页
⚫ Series对象类似于表格中的一个列,类似于一维数组,可以保存任何数据。
⚫ Series对象定义了NumPy的ndarray对象的接口__array__( ),因此可以用
NumPy的数组处理方法直接对Series对象进行处理。
⚫ Series对象除了支持使用整数位置作为下标存取元素之外,还支持使用索引
标签作为下标存取元素,这一功能与字典类似。
⚫ 每个Series对象都是由索引对象index和值对象values组成的:
◼ index: 从ndarray数组继承的Index索引对象,用于保存标签信息。若创建Series对象时不
指定index,将自动创建一个表示位置下标的整数索引。
◼ values: 保存元素值的一维ndarray数组。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第5页
⚫ 例如,创建一个表示各科目成绩的Series对象:
import pandas as pd
s1 = (data=[90, 60, 36, 75, 87], index=["语文", "政治", "历史", "地理", "英语"])
print("s1索引:", )
print("值数组:", , type())
s1索引: Index(['语文', '政治', '历史', '地理', '英语'], dtype='object')
值数组: [90 60 36 75 87] <class ''>
⚫ 执行语句print(s1),则输出: 语文 90
政治 60
历史 36
地理 75
英语 87
dtype: int64
元素类型为int64
元素
标签索引
第6页
s1对象类型为
Series
s1对象的shape为
(5, )
元素
标签索引
元素类型
第7页
index属性
第8页
索引标签自动成为s1的属性,例如
输出语文成绩:print(s1.语文)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第9页
⚫ 如果创建Series对象时未指定标签索引,则使用整数位置索引。例如:
s2 = (data=[90, 60, 36, 75, 87])
print("s2索引:", )
print("值数组:", , type())
print(s2)
s2索引: RangeIndex(start=0, stop=5, step=1)
值数组: [90 60 36 75 87] <class ''>
0 90
1 60
2 36
3 75
4 87
dtype: int64
整数位置索引
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第10页
⚫ Series对象的构造方法中的copy参数仅对数组和Series对象起作用,默认为
False,此时属性与data参数共享同一内存空间。例如:
import numpy as np
import pandas as pd
r = ([1, 2])
ser = (data=r, copy=False)
ser[0] = 999
print(ser)
print('-' * 20)
print(r)
0 999
1 2
dtype: int32
--------------------
[999 2]
0 999
1 2
dtype: int32
--------------------
[1 2]
若 copy=True
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第11页
⚫ Series对象的下标运算支持整数位置索引和标签索引两种形式,例如下面两
条命令都输出s1中的第一个元素90:
print(s1[0])
print(s1['语文'])
print(s1[1:3])
------------
政治 60
历史 36
dtype: int64
⚫ 若执行s1[0] +=2,则s1中的第一个元素将变为92。
⚫ Series对象还支持位置切片和标签切片:
⚫ 位置切片遵循Python的切片规则,包括起始位置,不包括结束位置;
⚫ 但是,标签切片包括结束标签。
语文 90
政治 60
历史 36
地理 75
英语 87
dtype: int64
print(s1['政治':'地理'])
------------
政治 60
历史 36
地理 75
dtype: int64
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第12页
⚫ Series对象的算术、比较和逻辑运算规则:
◼ s1 + k:s1[i]+k,得到一个新的序列,其中k为标量;
◼ s1 > k: s1[i]>k,得到一个新的布尔序列;
◼ s1 + s2:标签相同的对应元素相加,得到一个新的序列
◼ s1 > s2:标签相同的对应元素比较大小,得到一个新的布尔序列
◼ s3 & s4:标签相同的对应元素逻辑与,得到一个新的布尔序列
# 英语成绩
s_English = (data=[80, 70, 90], index=['张三', '李四', '王五'])
# 语文成绩
s_Chinese = (data=[85, 92, 74], index=['张三', '李四', '王五'])
张三 85
李四 75
王五 95
dtype: int64
s_English + 5
张三 165
李四 162
王五 164
dtype: int64
s_English + s_Chinese
张三 True
李四 False
王五 True
dtype: bool
s_English >= 80
张三 False
李四 False
王五 True
dtype: bool
s_English > s_Chinese
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第13页
⚫ Series对象的算术、比较和逻辑运算规则:
◼ s1 + k:s1[i]+k,得到一个新的序列,其中k为标量;
◼ s1 > k: s1[i]>k,得到一个新的布尔序列;
◼ s1 + s2:标签相同的对应元素相加,得到一个新的序列
◼ s1 > s2:标签相同的对应元素比较大小,得到一个新的布尔序列
◼ s3 & s4:标签相同的对应元素逻辑与,得到一个新的布尔序列
# 英语成绩
s_English = (data=[80, 70, 90], index=['张三', '李四', '王五'])
# 语文成绩
s_Chinese = (data=[85, 92, 74], index=['张三', '李四', '王五'])
s_English >= 80
张三 True
李四 False
王五 False
dtype: bool
s_English >= 80 & s_Chinese >= 80
张三 True
李四 True
王五 False
dtype: bool
s_Chinese >= 80
张三 True
李四 False
王五 True
dtype: bool
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第14页
⚫ Series对象的一些统计方法:
◼ sum( )、max( )、min( )、mean( )、std( )、describe( ) ;
# 语文成绩
s_Chinese = (data=[85, 92, 74], index=['张三', '李四', '王五'])
print('基本统计方法')
print(())
print(())
print(())
print('生成统计信息')
print(())
251
92
count
mean
std
min
25%
50%
75%
max
dtype: float64
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第15页
⚫ 获取长度:
◼ 使用系统函数len( );
◼ 访问Series对象的size属性
◼ 访问Series对象的shape属性
# 语文成绩
s_Chinese = (data=[85, 92, 74], index=['张三', '李四', '王五'])
print('获取Series对象的长度')
print(len(s_Chinese))
print()
print([0])
3
3
3
⚫ 获取开头或结尾的若干元素:Series对象的head( )和tail( )方法
print('获取开头两个元素')
print((2))
print('获取末尾两个元素')
print((2))
张三 85
李四 92
dtype: int64 李四 92
王五 74
dtype: int64
张三 85
李四 92
王五 74
dtype: int64
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第16页
⚫ 使用map( )方法映射或替换元素,返回一个新的序列:
◼ 通过一个指定的函数映射每一个元素;
◼ 根据字典替换元素,未在字典中出现的元素替换为NaN;
s = (['cat', 'dog', , 'rabbit'])
print('通过一个指定的函数映射每一个元素')
# 转换为大写,忽略空值
print((, na_action='ignore'))
# 格式化
print(('I am a {}'.format))
0 cat
1 dog
2 NaN
3 rabbit
dtype: object
print('根据字典替换')
print(({'cat': 'kitten', 'dog': 'puppy'}))
0 kitten
1 puppy
2 NaN
3 NaN
dtype: object
0 CAT
1 DOG
2 NaN
3 RABBIT
dtype: object0 I am a cat
1 I am a dog
2 I am a nan
3 I am a rabbit
dtype: object
s的每一个元素都传入upper( )方法
s的每一个元素都传入format( )方法
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第17页
⚫ 遍历元素
# 语文成绩
s_Chinese = (data=[85, 92, 74], index=['张三', '李四', '王五'])
for x in s_Chinese:
print(x)
⚫ 遍历标签和元素
# 标签和元素构成的二元组列表
print(list(()))
print('遍历标签和元素')
for x in ():
print(x)
85
92
74
('张三', 85)
('李四', 92)
('王五', 74)
[('张三', 85), ('李四', 92), ('王五', 74)]
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
Series对象
第18页
⚫ 当对两个Series对象进行操作符运算时,标签相同的两个元素进行计算,并
得到一个新的Series对象。
⚫ 当某一方的标签不存在时,默认以NaN(Not a Number)填充。由于NaN是
浮点数中的一个特殊值,因此输出的Series对象的元素类型被转换为float64
。例如:
s1 = ([90, 60, 36, 75, 87], index=["语文", "政治", "历史", "地理", "英语"])
s2 = ([72, 83, 66, 80], index=["政治", "历史", "语文", "英语"])
print(s1 + s2)
历史
地理 NaN
政治
英语
语文
dtype: float64
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
DataFrame 对象
第19页
⚫ DataFrame对象是二维表格型的数据结构。
◼ 它含有一组有序的列,同一列的所有数据的类型相同,每列可以是不同的类型。
◼ 数据框既有行索引也有列索引,默认是位置索引,但通常会指定标签索引(相当于表
格的列名和行名),还可以给列索引和行索引取名。
◼ 通常,各列含义各不相同,因此列索引也不相同,尽管允许相同。
列索引
行索引
Measures Name Gender Birthdate Chinese Math English
School Province
文学院
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院
山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
列索引名
行索引名
第1级行索引 values属性(二维数组)
index属性
columns属性
第0级行索引
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
DataFrame 对象
第20页
⚫ 数据框的3个主要属性:
⚫ values属性:用于表示数据框中数据集合,是一个NumPy二维ndarray数组,Pandas建议
使用to_numpy( )方法转换数据。
⚫ columns属性:用于存储列索引的Index或MultiIndex对象,包含列索引及列索引名。
⚫ index属性:用于存储行索引的Index或MultiIndex对象,包含行索引及行索引名。
列索引
行索引
Measures Name Gender Birthdate Chinese Math English
School Province
文学院
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院
山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
列索引名
行索引名
第1级行索引 values属性(二维数组)
index属性
columns属性
第0级行索引
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
DataFrame 对象
第21页
⚫ 数据框可看作由Series对象组成的字典,是存储Series对象的容器,每一列视
为一个Series对象,各Series对象的index属性相同,各列索引则对应每个
Series对象的name属性。
⚫ 数据框提供了字典式接口,用于访问每一列,返回的就是一个Series对象。
列索引
行索引
Measures Name Gender Birthdate Chinese Math English
School Province
文学院
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院
山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
列索引名
行索引名
第1级行索引 values属性(二维数组)
index属性
columns属性
第0级行索引
第22页
Name
School Province
文学院
山东 王琴
江苏 吴文
福建 盛红霞
理学院
山东 张艳
江苏 张冬
福建 尤珊珊
Series 1
Gender
School Province
文学院
山东 女
江苏 男
福建 男
理学院
山东 女
江苏 男
福建 女
Series 2
Measures Name Gender Birthdate Chinese Math English
School Province
文学院
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院
山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
DataFrame
English
School Province
文学院
山东 137
江苏 102
福建 142
理学院
山东 63
江苏 122
福建 76
Series 6
…
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
DataFrame 对象
第23页
⚫ 示例数据框中的数据来自一个CSV文件,该文件存储的是某高校大一新生
的部分入学数据,其中第一行为表头。
Measures Name Gender Birthdate Chinese Math English
School Province
文学院
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院
山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
DataFrame 对象
第24页
⚫ 现在通过pandas库的read_csv( )函数将其读入数据框中:
import pandas as pd
# 设置输出右对齐,
# 同时在"设置->编辑器->配色方案->控制台字体"中,
# 将控制台字体设置为中文字体,例如Simsun, SimHei
_option('_asian_width', True)
df_score = _csv("", index_col=[0, 1], parse_dates=["Birthdate"])
= "Measures" # 设置列索引名
print(df_score) 指定进行日期转换的列,
也可使用csv文件中的列序号4
csv文件中的第1列和第2列作为数据框
df_score的行索引(分别作为第0级和
第1级索引,School和Province分别作
为它们的行索引标签)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
DataFrame 对象
第25页
⚫ 现在通过pandas库的read_csv( )函数将其读入数据框中:
Measures Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
第26页
df_score对象类型为
DataFrame
shape为 (6, 6)
即6行6列
values部分
共6x6个元素
列索引
行索引,
有两级
每个列索引标签自动成
为数据框的一个属性,
对应一个Series对象
第27页
dtypes属性是描述数据
框各列类型的Series对象
Measures
Name object
Gender object
Birthdate datetime64[ns]
Chinese int64
Math int64
English int64
dtype: object
(1)查看dtypes属性
pandas中字符串列使用
object类型表示
第28页
Index(['Name', 'Gender', 'Birthdate', 'Chinese', 'Math', 'English'],
dtype='object', name='Measures')
(2)查看columns属性
Measures
['Name', 'Gender', 'Birthdate', 'Chinese', 'Math', 'English']
columns属性是存储列索引的Index或MultiIndex对象,
包含列索引及列索引名。
索引对象的name属性(多级索引则为names属性)和
values属性分别表示索引名和索引值
第29页
index属性是存储行索引的Index或MultiIndex对象,包
含行索引及行索引名。
索引对象的name属性(多级索引则为names属性)和
values属性分别表示索引名和索引值
MultiIndex([('文学院', '山东'),
('文学院', '江苏'),
('文学院', '福建'),
('理学院', '山东'),
('理学院', '江苏'),
('理学院', '福建')],
names=['School', 'Province'])
(3)查看index属性
['School', 'Province']
[('文学院', '山东'), ('文学院', '江苏'), ('文学院', '福建'),
('理学院', '山东'), ('理学院', '江苏'), ('理学院', '福建')]
第30页
[['王琴' '女' Timestamp('2002-05-26 00:00:00') 95 105 137]
['吴文' '男' Timestamp('2003-02-24 00:00:00') 68 68 102]
['盛红霞' '男' Timestamp('2003-03-22 00:00:00') 123 66 142]
['张艳' '女' Timestamp('2003-08-12 00:00:00') 97 119 63]
['张冬' '男' Timestamp('2001-03-31 00:00:00') 137 88 122]
['尤珊珊' '女' Timestamp('2002-11-26 00:00:00') 75 65 76]]
(4)查看values属性
values属性用于获取数据框中的NumPy二维ndarray数组,
也可以使用_numpy( )方法转换,得到数组
_numpy( )
第31页
(6, 6)
(5)查看shape和size属性
shape属性是一个二元组,表示二维表格的行数和列数,
其值与属性相同;
size属性表示二维表格中元素的数量,它等于二维表格
行数与列数的乘积。
36
第32页
School Province
文学院 山东 王琴
江苏 吴文
福建 盛红霞
理学院 山东 张艳
江苏 张冬
福建 尤珊珊
Name: Name, dtype: object
(6)查看单列和多列
df_score['Name'] 或 df_score[['Name','Gender','Chinese']]
Measures Name Gender Chinese
School Province
文学院 山东 王琴 女 95
江苏 吴文 男 68
福建 盛红霞 男 123
理学院 山东 张艳 女 97
江苏 张冬 男 137
福建 尤珊珊 女 75
单列是一个Series对象,
带着两级标签索引
获取多列,返回一个DataFrame对象,
带着两级标签索引
每个列索引标签自动成
为数据框的一个属性名,
对应一个Series对象
第33页
School Province
文学院 山东 王琴
江苏 吴文
福建 盛红霞
理学院 山东 张艳
江苏 张冬
福建 尤珊珊
Name: Name, dtype: object
(6)查看单列和多列
('Name') ('地址', default=None)
get( )方法也能获取单列,
返回一个Series对象
还可以指定默认值,当目标列
不存在时,就返回此默认值。
每个列索引标签自动成
为数据框的一个属性名,
对应一个Series对象
Measures Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
第34页
Measures
Name 吴文
Gender 男
Birthdate 2003-02-24 00:00:00
Chinese 68
Math 68
English 102
Name: (文学院, 江苏), dtype: object
(7)查看行
[('文学院', )]
通过在数据框的loc属性的[]运算符
中传入一个或一组行索引标签,
可以查看一行或多行。
Measures Name Gender Birthdate Chinese Math English
Province
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
[('文学院', '江苏')]
只有一行数据被
选出,因此返回
一个Series对象
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
创建数据框
第35页
⚫ 数据框的构造方法:
(data, index, columns, dtype, copy)
◼ data:一组类似二维数组的数据,可以是数据框、二维ndarray数组、能转换为二维数组
的嵌套列表、字典等可迭代对象,它包含存储在数据框中的数据(元素)。当data是字
典时,字典中的每个键值对将成为数据框的一列,值是一维数组、列表或 Series对象。
◼ index:行标签索引,是一组类似数组的数据,长度与data的表示数据的行数相同,其
元素必须是不可变对象;默认为 RangeIndex (0, 1, 2, …, m),m为行数。
◼ columns:列标签索引,是一组类似数组的数据,长度与data的表示数据的列数相同,
其元素必须是不可变对象;默认为 RangeIndex (0, 1, 2, …, n),n为列数。
◼ dtype:用于指定各列元素的数据类型,默认为None,系统可以自动判断数据类型,也
可以指定具体类型,但只能传入单个类型,即此时所有列都被限定为同一个类型。
◼ copy:是否复制传入的数据,默认为None。对于数据框或二维数组,默认值None等同
于copy=False;对于字典,默认值None等同于copy=True。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
几个通过构造方法创建数据框的示例
第36页
(1)data参数是二维数组的情形
A = ([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
df1 = (data=A)
df2 = (data=A,
columns=['a', 'b', 'c'])
df3 = (data=A,
columns=['a', 'b', 'c'],
index=['r1', 'r2', 'r3'])
0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
a b c
0 1 2 3
1 4 5 6
2 7 8 9
a b c
r1 1 2 3
r2 4 5 6
r3 7 8 9
未指定列索引和行索引,它
们默认都采用整数位置索引
指定了列索引,但行索引未
指定,故采用整数位置索引
指定了列索引和行索引
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
几个通过构造方法创建数据框的示例
第37页
(2)data参数是嵌套列表的情形
students = [['张三', '男', 23, , ],
['李四', '女', 21, , ],
['王五', '男', 25, , ]]
df4 = (data=students,
columns=['姓名', '性别', '年龄', '体重', '身高'])
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25
嵌套列表中的一个内嵌的列表,
对应数据框的一行数据
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
几个通过构造方法创建数据框的示例
第38页
(3)data参数是字典的情形
students = {
'姓名': ['张三', '李四', '王五'],
'性别': ['男', '女', '男'],
'年龄': [23, 21, 25],
'体重': [, , ],
'身高': [, , ]
}
df5 = (data=students)
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25
字典中的每个键值对作为数据框中
的一列,其中键作为列索引标签,
而值(列表或序列)作为该列数据
students = {
'姓名': (data=['张三', '李四', '王五']),
'性别': (data=['男', '女', '男']),
'年龄': (data=[23, 21, 25]),
'体重': (data=[, , ]),
'身高': (data=[, , ])
}
或者
值是一个列表
值是一个序列
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据框转换为其他格式的数据
第39页
⚫ 数据框提供了一系列to_*( )方法,以将其数据转换为其他格式。
⚫ 例如:
◼ to_dict( ):将其数据转换成字典
◼ to_record( ):将其数据转换成NumPy结构数组()
◼ to_numpy( ):将其数据转换成Numpy数组
◼ to_string( ):将其数据转换成字符串
◼ to_json( ):将其数据转换成JSON字符串
◼ to_csv( ):将其数据保存到CSV文件
◼ to_excel( ):将其数据保存到excel文件
◼ to_sql( ) :将其数据写入到SQL数据库
数据导出到外部,将在节介绍
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)转换为字典
第40页
⚫ to_dict( )方法可以将数据框转换为字典,它的orient参数决定了字典元素的
类型,该参数的常用取值有list和records。
◼ "list":数据框的每列转换为键值对,列索引转换为键,列数据转换为值列表,to_dict( )
返回的是一个值为列表的字典。
◼ "records":数据框的每行(一行视为一条记录)转换为一个字典,to_dict( )返回的是一
个元素为字典的列表。
{'体重': [, , ],
'姓名': ['张三', '李四', '王五'],
'年龄': [23, 21, 25],
'性别': ['男', '女', '男'],
'身高': [, , ]}
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25
_dict(orient='list')
[{'姓名': '张三', '性别': '男', '年龄': 23, '体重': , '身高': },
{'姓名': '李四', '性别': '女', '年龄': 21, '体重': , '身高': },
{'姓名': '王五', '性别': '男', '年龄': 25, '体重': , '身高': }]
_dict(orient='records')
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)转换为NumPy结构数组
第41页
⚫ to_numpy( )方法可以将数据框转换为NumPy结构数组(recarray),元素类型为
dtype[void],它表示一条记录();index参数默认为True,表示每
条记录中包含行索引。数据框的每一行将转换为结构数组中的一个记录。
(, [('index', '<i8'), ('姓名', 'O'), ('性别', 'O'),
('年龄', '<i8'), ('体重', '<f8'), ('身高', '<f8')])
records = _records ( )
[(0, '张三', '男', 23, , ) (1, '李四', '女', 21, , )
(2, '王五', '男', 25, , )]
8字节的int类型,小端法存储
(低字节在前,高字节在后)
object类型 8字节的float类型,
小端法存储
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(3)转换为Numpy数组
第42页
⚫ to_numpy( )方法可以将数据框转换为Numpy二维数组。
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25 = _numpy()
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)转换为字符串
第43页
⚫ to_string( )方法可以将数据框转换为字符串。
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25 _str = _string()
print
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(5)转换为JSON字符串
第44页
⚫ to_json( )方法可以将数据框转换为JSON字符串。orient参数指定转换方向,
常用值:
◼ 'split':按数据框的values、columns和index属性形成JSON, 对应的键分别为data、columns
和index,形如:"{'data':[[]], 'columns':[], 'index':[]}"。
◼ 'records':按记录转换字典列表对应的JSON字符串,每一个字典中,列索引标签作为键
,行中元素作为值。
◼ 'columns':按列转换为字典对应的JSON字符串,列索引标签作为键,列元素及其位置
索引构成的字典作为值。
◼ 'index':按列转换为字典对应的JSON字符串,行索引标签作为键,记录对应的字典作
为值。
第45页
_json(orient='split', force_ascii=False)
{"columns":["姓名","性别","年龄","体重","身高"],
"index":[0,1,2],
"data":[["张三","男",23,,],
["李四","女",21,,],
["王五","男",25,,]]
}
_json(orient='records', force_ascii=False)
[{"姓名":"张三","性别":"男","年龄":23,"体重":,"身高":},
{"姓名":"李四","性别":"女","年龄":21,"体重":,"身高":},
{"姓名":"王五","性别":"男","年龄":25,"体重":,"身高":}]
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25
第46页
_json(orient='columns', force_ascii=False)
{"姓名":{"0":"张三","1":"李四","2":"王五"},
"性别":{"0":"男","1":"女","2":"男"},
"年龄":{"0":23,"1":21,"2":25},
"体重":{"0":,"1":,"2":},
"身高":{"0":,"1":,"2":}
}
_json(orient='index', force_ascii=False)
{"0":{"姓名":"张三","性别":"男"年",龄":23,"体重":,"身高":},
"1":{"姓名":"李四","性别":"女","年龄":21,"体重":,"身高":},
"2":{"姓名":"王五","性别":"男","年龄":25,"体重":,"身高":}
}
姓名 性别 年龄 体重 身高
0 张三 男 23
1 李四 女 21
2 王五 男 25
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据框数据存取
第47页
⚫ 数据框中数据存取的方式有很多,除了可使用[ ]运算符,也可使用loc[ ]、
iloc[ ]、at[ ]和iat[ ]下标存取器。此外,还可使用get( )、head( )、tail( )、query( )
、nlargest( )和nsmallest( )等方法。
⚫ 先产生一个数据框df,主要以它为例来介绍这些存取方式:
A = [[5, 0, 3],
[3, 7, 9],
[3, 5, 2],
[4, 7, 6],
[8, 8, 1]] # 数据
columns = ["c1", "c2", "c3"] # 列索引
index = ["r1", "r2", "r3", "r4", "r5"] # 行索引
df = (data=A, columns=columns, index=index)
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
[ ]运算符
第48页
⚫ 通过[ ]运算符存取DataFrame对象时,支持以下几种形式的下标对象:
◼ 单个索引标签:获取标签对应的列,返回一个Series对象。
◼ 多个索引标签 :获取以列表、数组(注意不能是元组)表示的多个标签对应的列,
返回一个DataFrame对象。
◼ 整数切片:以整数下标获取切片对应的行。
◼ 标签切片:当使用标签作为切片时包含终值。
◼ 一维布尔类数组(array-like,数组、列表或Series等):获取类数组中True对应的行。
◼ 二维布尔类数组(数组、嵌套列表或数据框等):False对应的元素设置为NaN。
存取列
存取行
df df['c2'] # 获取单列 df[ ['c1', 'c3'] ] # 获取多列
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
r1 0
r2 7
r3 5
r4 7
r5 8
Name: c2, dtype: int64
c1 c3
r1 5 3
r2 3 9
r3 3 2
r4 4 6
r5 8 1
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
[ ]运算符
第49页
⚫ 通过[ ]运算符存取DataFrame对象时,支持以下几种形式的下标对象:
◼ 单个索引标签:获取标签对应的列,返回一个Series对象。
◼ 多个索引标签 :获取以列表、数组(注意不能是元组)表示的多个标签对应的列,
返回一个DataFrame对象。
◼ 整数切片:以整数下标获取切片对应的行。
◼ 标签切片:当使用标签作为切片时包含终值。
◼ 一维布尔类数组(array-like,数组、列表或Series等):获取类数组中True对应的行。
◼ 二维布尔类数组(数组、嵌套列表或数据框等):False对应的元素设置为NaN。
存取列
存取行
df df[2:4] df['r2':'r4']
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
r1 True
r2 False
r3 False
r4 True
r5 True
Name: c1, dtype: bool
c1 c2 c3
r1 5 0 3
r4 4 7 6
r5 8 8 1
df[[True, False, False, True,True]]
>3 df[>3]
c1 c2 c3
r3 3 5 2
r4 4 7 6
c1 c2 c3
r2 3 7 9
r3 3 5 2
r4 4 7 6
用途:选择
满足条件的
行。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
[ ]运算符
第50页
⚫ 通过[ ]运算符存取DataFrame对象时,支持以下几种形式的下标对象:
◼ 单个索引标签:获取标签对应的列,返回一个Series对象。
◼ 多个索引标签 :获取以列表、数组(注意不能是元组)表示的多个标签对应的列,
返回一个DataFrame对象。
◼ 整数切片:以整数下标获取切片对应的行。
◼ 标签切片:当使用标签作为切片时包含终值。
◼ 一维布尔类数组(array-like,数组、列表或Series等):获取类数组中True对应的行。
◼ 二维布尔类数组(数组、嵌套列表或数据框等):False对应的元素设置为NaN。
存取列
存取行
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
df>2 df[df>2]
c1 c2 c3
r1 True False True
r2 True True True
r3 True True False
r4 True True True
r5 True True False
c1 c2 c3
r1 5 NaN
r2 3
r3 3 NaN
r4 4
r5 8 NaN
不满足条件的元素置为NaN
数据框的where( )方法已
经实现了该功能,调用
(df > 2)的作用
与df[df > 2]的相同。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
loc[ ]和iloc[ ]存取器
第51页
⚫ loc[ ]存取器的完整用法是向下标传入行标签索引和列标签索引构成的元组
,即形如loc[ 行下标,列下标 ]。
◼ 若下标不是元组,则该下标对应数据框的第0轴,即仅指定行下标,列下标省略,因此
获取某些行。
◼ 每个轴的下标的用法都非常灵活,可以是单个标签、标签列表、标签切片以及布尔类
数组对象。
⚫ iloc[ ]存取器的用法与loc[ ]存取器的类似,但是其下标使用整数位置索引进
行定位,而不是标签索引。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
1、loc[ ]存取器
第52页
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
# r2行
['r2']
# r2和r4行
[['r2', 'r4']]
c1 3
c2 7
c3 9
Name: r2, dtype: int64
c1 c2 c3
r2 3 7 9
r4 4 7 6
# 切片:r2~r4行
['r2':'r4']
c1 c2 c3
r2 3 7 9
r3 3 5 2
r4 4 7 6
#单个元素,r2行c3列
['r2', 'c3']
9
# r2行,c1、c3列
['r2', ['c1', 'c3']]
c1 3
c3 9
Name: r2, dtype: int64
# r2行,c1~c3列
['r2', 'c1':'c3']
c1 3
c2 7
c3 9
Name: r2, dtype: int64
# r2~r4行、c3列
['r2':'r4', 'c3']
# r2~r4行、c2~c3列
['r2':'r4', 'c2':'c3']
r2 9
r3 2
r4 6
Name: c3, dtype: int64
c2 c3
r2 7 9
r3 5 2
r4 7 6
行标签和列
标签都指明
仅指明了行标签,则选择所有列
行标签和列标签都指明
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
1、loc[ ]存取器
第53页
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1 用冒号“:”显式指明要所有列
#r2行
['r2', :]
# r2~r4行
['r2':'r4', :]
c1 3
c2 7
c3 9
Name: r2, dtype: int64
c1 c2 c3
r2 3 7 9
r3 3 5 2
r4 4 7 6
# c1列
[:, 'c1']
r1 5
r2 3
r3 3
r4 4
r5 8
Name: c1, dtype: int64
# c1、c3列
[:, ['c1', 'c3']]
# 所有行、所有列
[:, :]
c1 c3
r1 5 3
r2 3 9
r3 3 2
r4 4 6
r5 8 1
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
# c2>5的行
[>5]
c1 c2 c3
r2 3 7 9
r4 4 7 6
r5 8 8 1
# c2>5的行,c2、c3列
[>5,'c2':'c3']
c2 c3
r2 7 9
r4 7 6
r5 8 1
一维布尔类数组作为行标签
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
2、iloc[ ]存取器
第54页
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
# 第2行
[1]
# 第2行和第4行
[[1, 3]]
c1 3
c2 7
c3 9
Name: r2, dtype: int64
c1 c2 c3
r2 3 7 9
r4 4 7 6
# 切片:第2~4行
[1 : 4]
c1 c2 c3
r2 3 7 9
r3 3 5 2
r4 4 7 6
# 第2~4行、第3列
[1:4, 2])
# 第2~4行、第2~3列
[1:4, 1:3])
r2 9
r3 2
r4 6
Name: c3, dtype: int64
c2 c3
r2 7 9
r3 5 2
r4 7 6
# 第2列>5的行,第2、3列
[>5,1:3]
c1 c2 c3
r2 3 7 9
r4 4 7 6
r5 8 8 1
c2 c3
r2 7 9
r4 7 6
r5 8 1
# 第2列>5的行
[>5]
布尔型Series对象,由于带有索引项,不能作为iloc[ ]
的下标,但可以使用其values属性,或者list(>5)
iloc[ ]的下标只能是整数、整数列表、整数切片、布尔列表或布尔数组
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
2、iloc[ ]存取器
第55页
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
# 第1列
[:, 0]
# 第1、3列
[:, [0,2]]
r1 5
r2 3
r3 3
r4 4
r5 8
Name: c1, dtype: int64
c1 c3
r1 5 3
r2 3 9
r3 3 2
r4 4 6
r5 8 1
# 所有行,所有列
[:, :]
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
用冒号“:”显式指明要所有行或所有列
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
at[ ]和iat[ ]存取器
第56页
⚫ at[ ]和iat[ ]存取器专用于获取数据框中的单个元素,分别使用标签和整数位置
索引下标,它们的功能也可以使用loc[ ]和iloc[ ]存取器来实现。
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
['r2', 'c3'] # r2行、c3列 [1, 2] # 第2行、第3列
9 9
df['c3'][1] 、df['c3']['r2']、[1] 或 ['r2']也是获取单个元素,
等价于:s = df['c3'] 或 s= # 先获取c3列(一个Series)
s[1] 或 s['r2']
等价于:['r2', 'c3']
或: ['r2']['c3']
等价于:[1, 2]
或:[1][2]
先获取行(一个Series)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
多级标签的存取
第57页
⚫ loc[ ]和at[ ]存取器的下标可以指定多级索引中每级索引的标签。
◼ 这时多级索引所在轴对应的下标是标签元组,其中每个元素与索引中的每级索引对应。
⚫ 多级行索引标签的各种使用情形:
①仅限定第0级索引标签,而第1级索引标签不限定,形如“('文学院', )”:
Measures Name Chinese
School Province
文学院 山东 王琴 95
江苏 吴文 68
福建 盛红霞 123
[('文学院', ), ['Name', 'Chinese']]
Measures Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
元组('文学院', )也可以明确表示为
('文学院', slice(None)),或者 _['文学院', :]
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
多级标签的存取
第58页
②两级索引标签都限定,形如“('文学院', '江苏')”:
Measures
Name 吴文
Chinese 68
Name: (文学院, 江苏), dtype: object
[('文学院', '江苏'), ['Name', 'Chinese']]
Measures Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
③仅限定第1级索标签,而第0级索引标签不限定,形如“(slice(None), '江苏')”:
Measures Name Chinese
School Province
文学院 江苏 吴文 68
理学院 江苏 张冬 137
[(slice(None), '江苏'), ['Name', 'Chinese']]
此时,列标签不能省略
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
get( )方法
第59页
⚫ get(col_label, default)方法用于获取数据框的某列,其用法与字典的get( )方法
类似:
◼ 参数col_label用于指定某个列索引标签。
◼ 参数default用于指定当列不存在时,方法的返回值。
◼ 方法返回参数col_label指定的列。如果该列存在,则返回该列对应的Series对象;否则,
返回default参数(默认为None)指定的默认值。
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
('c2') # c2列 ('c4',default='无') # c4列
r1 0
r2 7
r3 5
r4 7
r5 8
Name: c2, dtype: int64
无
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
head( )和tail( )方法
第60页
⚫ head(n=5)和tail(n=5)方法分别用于获取数据框开头n行数据和末尾n行数据。
⚫ 例如,显示df_score中的开头2行:
Measures Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
(2)
Measures Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
nlargest( ) 和nsmallest( )方法
第61页
⚫ nlargest(n, columns, keep='first')方法根据指定的列标签降序排列后,返回数据
框的前n行。该方法大致等同于sort_values(columns, ascending=False).head(n)。
◼ columns参数:指定排序的列,可以是单列(标签),也可以是多列(标签列表)。
◼ keep参数:表示排序后,如何取舍那些重复的记录,各取值含义:
◆ 'first':保留第1行,此时返回的行数不大于n。
◆ 'last':保留最后1行,此时返回的行数不大于n。
◆ 'all':保留所有重复行,此时返回的行数可能大于n。
⚫ 例如,给定关于国家人口、国内生产总值(Gross Domestic Product,GDP)
等信息的数据框df_country:
第62页
df_country = (
data={
'population': [59000000, 65000000, 434000, 434000, 434000, 337000, 11300, 11300, 11300],
'GDP': [1937894, 2583560, 12011, 4520, 12128, 17036, 182, 38, 311],
'alpha-2': ['IT', 'FR', 'MT', 'MV', 'BN', 'IS', 'NR', 'TV', 'AI']},
index=['Italy', 'France', 'Malta', 'Maldives', 'Brunei', 'Iceland', 'Nauru', 'Tuvalu', 'Anguilla']
)
population GDP alpha-2
Italy 59000000 1937894 IT
France 65000000 2583560 FR
Malta 434000 12011 MT
Maldives 434000 4520 MV
Brunei 434000 12128 BN
Iceland 337000 17036 IS
Nauru 11300 182 NR
Tuvalu 11300 38 TV
Anguilla 11300 311 AI
(3, 'population')
population GDP alpha-2
France 65000000 2583560 FR
Italy 59000000 1937894 IT
Malta 434000 12011 MT
(3, 'population', keep='last')
population GDP alpha-2
France 65000000 2583560 FR
Italy 59000000 1937894 IT
Brunei 434000 12128 BN
(3, 'population', keep='all')
population GDP alpha-2
France 65000000 2583560 FR
Italy 59000000 1937894 IT
Malta 434000 12011 MT
Maldives 434000 4520 MV
Brunei 434000 12128 BN
第63页
population GDP alpha-2
Italy 59000000 1937894 IT
France 65000000 2583560 FR
Malta 434000 12011 MT
Maldives 434000 4520 MV
Brunei 434000 12128 BN
Iceland 337000 17036 IS
Nauru 11300 182 NR
Tuvalu 11300 38 TV
Anguilla 11300 311 AI
(3, ['population', 'GDP'])
population GDP alpha-2
France 65000000 2583560 FR
Italy 59000000 1937894 IT
Brunei 434000 12128 BN
⚫ 按多列排序的情况。例如,columns=['population', 'GDP'],则nlargest( )方法返回
df_country中先按population降序、然后按GDP降序排列后的前3行:
⚫ nsmallest( )方法与nlargest( )方法类似,根据指定的列标签升序排列后,返回数据
框的前n行,该方法大致等同于sort_values(columns, ascending=True).head(n)。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
query( )方法
第64页
⚫ 前面讲到,通过一维布尔类数组下标可以从数据框中选择满足条件的行。
⚫ 例如,从数据框df中选择c1列大于3且c3列小于5的行:
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
df[(>3) & (<5) ]
c1 c2 c3
r1 5 0 3
r5 8 8 1
多个条件连接时需要用括号将各比较
运算括起来。这样,下标相对繁琐。
⚫ 使用数据框的query( )方法可以简化上述操作,其查询条件表示成字符串,写
法类似于结构化查询语言(Structured Query Language,SQL)中的where条件
子句,例如>3表示成c1>3。多个条件采用and、or和not进行连接。
⚫ 例如:df[(>3) & (<5)]可以简化为('c1>3 and c3<5')。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
query( )方法
第65页
⚫ 同时,与SQL类似,query( )方法也支持参数化查询,即在查询中可以通过符
号@嵌入变量,从而拼凑查询字符串
⚫ 当然,还可以采用格式化字符串的形式来完成。
df
c1 c2 c3
r1 5 0 3
r2 3 7 9
r3 3 5 2
r4 4 7 6
r5 8 8 1
expr = 'c1>3 and c3<5'
(expr=expr)
c1 c2 c3
r1 5 0 3
r5 8 8 1
x, y = 3, 5
expr = 'c1>@x and c3<@y'
(expr=expr)
x, y = 3, 5
expr = f'c1>{x} and c3<{y}'
(expr=expr)
c1 c2 c3
r1 5 0 3
r5 8 8 1
c1 c2 c3
r1 5 0 3
r5 8 8 1
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据读取与保存
第66页
⚫ Pandas提供了便利的接口从不同数据源(例如文件、数据库等)读取数据到
数据框,或将数据框数据写入外设。常用输入函数与输出方法分别见表9-1
和表9-2。注意,输入函数属于Pandas库,而输出方法是数据框的实例方法。
函数 说明
_csv() 用于从文本文件(例如CSV文件)读取数据至数据框
_excel() 用于从Excel文件读取数据至数据框
_sql() 用于从SQL数据库的查询结果载入数据至数据框
方法 说明
_csv() 用于将数据框数据写入文本文件(例如CSV文件)
_excel() 用于将数据框数据写入Excel文件
_sql() 用于将数据框数据写入SQL数据库
表9-1 数据框常用输入函数
表9-2 数据框常用输出方法
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
读写文本文件
第67页
⚫ _csv( )函数用于从文本文件读取数据至数据框。该函数拥有50多个参
数,用法非常灵活, 必选参数filepath_or_buffer用于指定文件路径或者已经
打开的文件,其余参数为可选,常用参数见表9-3。
表9-3 _csv()函数主要可选参数
参数 说明
sep 用于指定数据的分隔符号,可以是RE,默认值为逗号
skipinitialspace
有时CSV文件为了便于阅读,在逗号之后添加一些空格以对齐每列的数
据。如果希望忽略这些空格,可以将skipinitialspace参数设置为True
delim_whitespace
如果数据使用空格或制表符分隔,则不需要设置sep参数,而是将
delim_whitespace参数设置为True
header
用于指定作为列名的行号,数据从header+1行开始读取。默认情况下第
一行文本作为列索引标签。如果数据文件中没有保存列名的行,可以设置
header参数为None,使用names参数来指定列索引
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
读写文本文件
第68页
表9-3 _csv()函数主要可选参数(续表)
参数 说明
names 如果数据中不包含列名,则可以通过names参数指定列索引
skiprows
如果数据前面包含一些说明行,则可以使用该参数指定数据开始的行号,
从而跳过这些说明行
usecols 用于指定需要读入的列,默认读入所有列
index_col 用于指定建立行索引的列,默认没有行索引标签
parse_dates 用于指定将字符串转换为时间序列
encoding
如果数据中包含中文,可以使用该参数指定文件的编码格式,例如UTF-8、
GBK等
na_values 用于指定NaN对应的字符串列表,即哪些字符串表示缺失值
chunksize
当文件很大时,可以用chunksize参数指定一次读入的行数。当使用
chunksize时,read_csv()返回一个迭代器
第69页
⚫ 例如,从文件中读取数据到数据框,其中第1~2列(School和Province列)作
为行索引,Name、Birthdate和Chinese列作为数据,且将Birthdate列转换为日期类型:
Measures Name Birthdate Chinese
School Province
文学院 山东 王琴 2002-05-26 95
江苏 吴文 2003-02-24 68
福建 盛红霞 2003-03-22 123
理学院 山东 张艳 2003-08-12 97
江苏 张冬 2001-03-31 137
福建 尤珊珊 2002-11-26 75
df_score = _csv(
filepath_or_buffer="", # 指定文件路径
usecols=['School', 'Province', 'Name', 'Birthdate', 'Chinese'], # 指定需要读入的列
index_col=[0, 1], # 指定所谓行索引的列
parse_dates=["Birthdate"] # 指定需要转换为日期类型的列
)
= "Measures" # 设置列索引名
或为已打开的文件file:file = open('', 'tr', encoding='utf-8')
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
读写文本文件
第70页
⚫ 数据框的to_csv( )方法用于将其数据写入文本文件。filepath_or_buffer参数为
必选参数,用于指定文件路径或者事先已经打开的文件,其余参数都是可选
的,常用可选参数见表9-4。
表9-4 _csv()方法主要可选参数
参数 说明
sep 用于指定数据的分隔符号,默认为逗号
columns 用于指定要输出的列,默认输出所有列
header 用于指定列标签索引是否作为表头输出,默认为True
index 用于指定是否输出行索引,默认为True
index_label 用于指定要输出的各级行索引,默认输出所有级别的行索引
date_format
用于指定日期输出格式,例如'%Y-%m-%d %H:%M:%s'表示输出日期和时
间,'%Y-%m-%d'表示仅输出日期
encoding 用于指定字符编码格式,例如UTF-8、GBK等
第71页
⚫ 例如,将df_score中的数据输出至文件:
_csv(
path_or_buf='', # 指定文件名或打开的文件
sep=',', # 指定分隔符
columns=['Name', 'Birthdate', 'Chinese'], # 指定哪些列需要输出
header=True, # 指定列标签索引是否作为表头输出。如果给出了字符串列表, 则假定它是列名的别名。
index=True, # 指定是否输出行索引
index_label=['School', 'Province'], # 指定要输出行索引
date_format='%Y-%m-%d %H:%M:%s', # 指定日期输出格式
encoding='utf-8-sig' # 指定字符编码
)
如果字符编码格式用UTF-8,记事
本等文本编辑器能正确显示中文,
但用Excel打开中文显示乱码,而
用utf-8-sig格式则没有问题。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
读写Excel文件
第72页
⚫ _excel( )函数用于从Excel文件读取数据到数据框,参数与read_csv( )的
类似,但需要安装xlrd模块(执行安装命令pip install xlrd即可)。
⚫ 文件的末尾几行数据如图所示:
第73页
⚫ 读取该文件中的数据至数据框,并显示末尾5行数据:
Measures Name Birthdate Chinese Math English
School Province
理学院 福建 马兰英 2002-12-17 60
文学院 江苏 雷艳 2002-04-26 NaN NaN 126
福建 高建 2001-03-04 104
上海 陈磊 2001-05-29 90
理学院 江苏 宋雷 2003-12-18 135
df_score = _excel(
"", # 指定文件路径
usecols=['School', 'Province', 'Name', 'Birthdate', 'Chinese', 'Math', 'English'], # 需要读入的列
index_col=[0, 1], # 指定作为行索引的列
parse_dates=["Birthdate"], # 指定需要转换为日期类型的列
na_values=['-'] # excel中的单元格为 '-' 表示空值
)
= "Measures" # 设置列索引名
print(())
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
读写Excel文件
第74页
⚫ 数据框的to_excel( )方法用于将其数据写入Excel文件,参数与to_csv( )的类似
,但需要安装openpyxl模块(执行安装命令pip install openpyxl即可)。
⚫ 其常用可选参数:
参数 说明
sheet_name 它是指包含DataFrame对象的工作表的名称,默认为'Sheet1'
columns 用于指定要输出的列,默认输出所有列
header
列标签索引是否作为表头输出,默认为True。如果给出了字符串列表,则它
是列名的别名
index 用于指定是否输出行索引,默认为True
index_label 用于指定要输出的各级行索引,默认输出所有级别的行索引
na_repr 缺失值的替代值
startrow 输出的起始行序号,默认为0
startcol 输出的起始列序号,默认为0
engine 用于写入要使用的引擎,openpyxl或xlsxwriter
merge_cells 用来决定索引相同的相邻单元格是否合并,默认为True
第75页
⚫ 例如,将上例中数据框df_score的数据保存至Excel文件:
_excel(
'', # 文件名
sheet_name='Sheet1', # 指定表单名称
header=True, # 列索引作为表头输出
index=True, # 要输出行索引
na_rep='--', # 缺失值的替代值
merge_cells=False # 索引相同的相邻单元格不合并
)
缺失值替换成了字符串“--”;
行索引和列索引自动被加粗。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
读写SQL数据库
第76页
(1)SQLAlchemy简介
(2)写入SQL数据库
(3)读取SQL数据库
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)SQLAlchemy简介
第77页
⚫ SQLAlchemy是Python SQL工具包和对象关系映射器(Object Relational Mapper
,ORM),为应用程序开发人员提供了SQL的全部功能和灵活性。
⚫ ORM的主要功能是将数据库表中的每条记录映射成一个对象。所有的数据
库操作,都可转换为对象的操作。这样可以增加代码的可读性和安全性。当
然,使用ORM的效率低于直接执行SQL语句的。目前,许多主流的语言都实
现了ORM的库。
⚫ 执行pip命令“pip install sqlalchemy”便可安装SQLAlchemy包。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)SQLAlchemy简介
第78页
⚫ 在使用SQLAlchemy访问数据库时,首先需要使用_engine( )函
数创建一个用于建立连接到数据库的引擎,基本创建方法:
engine = _engine(url, encoding, echo, future, pool_size, pool_recycle)
⚫ 其中url参数是一个用于描述如何连接到数据库的字符串,其基本格式为:
dialect[+driver]://user:password@host/dbname
◼ dialect:表示数据库类型(例如MySQL、SQLite等)
◼ driver:表示使用的数据库API(例如PyMySQL、MySQL connector、PySQLite等)
◼ user、password、host、dbname :分别表示用户名、密码、服务器主机名(或IP地址)和
数据库名
◼ 例如:mysql+mysqlconnector://root:123@localhost/test
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)SQLAlchemy简介
第79页
⚫ 在使用SQLAlchemy访问数据库时,首先需要使用_engine( )函
数创建一个用于建立连接到数据库的引擎,基本创建方法:
engine = _engine(url, encoding, echo, future, pool_size, pool_recycle)
⚫ 其他参数:
◼ encodging:字符编码。
◼ echo:设置为True时会输出日志,这样就可以查看调用的具体SQL语句,方便调试代码
。
◼ pool_size:连接池的大小默认为5,设置为0时表示连接无限制。
◼ pool_recycle:设置时间以限制数据库在一段时间内没连接就自动断开。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)SQLAlchemy简介
第80页
⚫ 4个创建引擎的示例:
# ① 使用pymysql连接MySQL
engine = _engine(url="mysql+pymysql://user:pwd@host/dbname",
echo=True, pool_size=8, pool_recycle=3600)
# ② 使用mysqlconnector连接MySQL
engine = _engine(url="mysql+mysqlconnector://user:pwd@host/dbname",
echo=True, pool_size=8, pool_recycle=3600)
# ③ 连接SQLite
engine = _engine(url="sqlite:///", echo=True)
# ④ 连接内存SQLite
engine = _engine(url="sqlite///:memory:", echo=True)
⚫ 若要连接到MySQL数据库,需要安装pymysql或mysqlconnector包。
⚫ 若要连接到SQLite数据库,在Python 3中直接使用标准库中的sqlite3即可。
⚫ 数据库引擎的execute( )方法可以用于执行SQL语句,例如删除表:
('DROP TABLE score') # 执行SQL语句
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)写入SQL数据库
第81页
⚫ 数据框的to_sql( )方法可以将数据写入SQL数据库。
⚫ 其主要参数:
参数 说明
name 用于指定数据要写入数据库中的表的名称
con
用于指定连接数据库的方式,可以是 或
。推荐使用sqlalchemy的engine类型,因为采用SQLAlchemy
可以使用该库支持的任何数据库,包括SQLite
if_exists
当数据库中已经存在数据表时对数据表的操作:replace—替换,append—追加,
fail—当表存在时提示ValueError
index 用于指定数据框的行索引是否作为数据写入数据表,默认为True
index_label 用于指定需要写入数据表的各级索引的名称列表,默认输出所有级别的行索引
dtype 用于指定写入数据表的各列对应的数据类型
第82页
⚫ 例如,从 文件读取数据至数据框 df_score,然后保存至 SQLite数据库
的score表中:
import pandas as pd
import sqlalchemy
df_score = _csv(
filepath_or_buffer="", # 指定文件路径或打开的文件
index_col=[0, 1], # 指定行索引的列
parse_dates=["Birthdate"] # 指定需要转换为日期类型的列
)
= "Measures" # 设置列索引名
print(df_score)
# 连接SQLite
engine = _engine(url="sqlite:///", echo=True)
# df_score写入数据库
_sql(name='score', con=engine, if_exists='replace', index=True)
程序运行后,会在程序目录中
创建数据库文件
第83页
⚫ 如果用SQLite Expert查看刚才写入的数据表score,可以看到如图所示的结果:
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(3)读取SQL数据库
第84页
⚫ _sql( )函数用于从SQL数据库读取数据到数据框:
◼ sql参数用于指定查询数据的SQL语句;
◼ con参数用于指定数据库连接引擎;
◼ 其余参数的作用与read_csv( )等读取函数的类似。
⚫ 例如,从中的socre表中读取所有数据:
df_score2 = _sql(
sql="select * from score where School='理学院'",
con=engine,
index_col=['School', 'Province'],
parse_dates=['Birthdate']
)
Name Gender Birthdate Chinese Math English
School Province
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
操作数据框
第85页
⚫ Pandas数据框提供了一系列方法用于修改其结构,以满足不同的使用需求。
◼ 修改列索引与行索引
◼ 添加列、插入新列与删除列
◼ 调整列顺序
◼ 添加行与删除行
◼ 按索引排序与按值排序
◼ 列值转换为行索引与行索引转换为列值
◼ 数据透视与数据融合
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
修改列索引与行索引
第86页
⚫ 修改索引有两种办法:
(1)直接修改index或columns属性
df = ({"A": [1, 2, 3], "B": [4, 5, 6]})
= ["AA", "BB"] # 修改列索引
A B
0 1 4
1 2 5
2 3 6
(2)调用rename( )方法。其主要参数:
◼ mapper:映射函数,可以对索引进行某种变换。
◼ axis:整数或字符串类型,可以是轴名称('index'、'columns')或数字(0、1),默
认为'index'。
◼ index:行标签旧名与新名的映射关系的字典。
◼ columns:列标签旧名与新名的映射关系的字典。
◼ copy:表示是否复制基础数据,默认为True。
◼ inplace:默认为False,返回一个新的数据框。否则为True,忽略copy参数,修改数
据框自身。
AA BB
0 1 4
1 2 5
2 3 6
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
修改列索引与行索引
第87页
df1 = (columns={"AA": "a", "BB": "c"})
df2 = (index={0: "x", 1: "y", 2: "z"})
df3 = (mapper=, axis='columns')
(columns={"AA": "a", "BB": "c"}, inplace=True)
df df1 df2 df3 df
AA BB
0 1 4
1 2 5
2 3 6
a c
0 1 4
1 2 5
2 3 6
AA BB
x 1 4
y 2 5
z 3 6
aa bb
0 1 4
1 2 5
2 3 6
a c
0 1 4
1 2 5
2 3 6
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加列、插入新列与删除列
第88页
(1)添加列
◼ 数据框可以看作Series对象的字典,因此通过DataFrame[colname] = values即可添加新列,
values可以是列表、Series等类数组对象。例如:
df = ({"A": [1, 2, 3], "B": [4, 5, 6]})
df['C'] = [7, 8, 9] # 列表添加到新列
df['D'] = (data=[1, 1, 0]) # Series添加到新列
df['E'] = *10 # Series参与运算后的结果添加到新列
A B C D E
0 1 4 7 1 40
1 2 5 8 1 50
2 3 6 9 0 60
◼ ( )方法添加由关键字参数指定的列,它总是返回一个新的数据框,原数
据框的内容保持不变。如果该列已经存在,则进行覆盖。例如,为df增加标签为F的列:
df1 = (F=+2)
A B C D E F
0 1 4 7 1 40 6
1 2 5 8 1 50 7
2 3 6 9 0 60 8
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加列、插入新列与删除列
第89页
(2)插入新列
◼ ( )方法用于在指定列序号位置插入新列。loc参数用于指定插入列的位置序
号, column参数用于指定新列的标签,value参数是新列的值,可以是类数组。例如:
df = ({"A": [1, 2, 3], "B": [4, 5, 6]})
(loc=0, column='C', value=[7, 8, 9]) # 在第1列前插入C列
(loc=2, column='D', value=([1, 0, 5])) # 在第3列前插入D列
df变化:
A B
0 1 4
1 2 5
2 3 6
C A B
0 7 1 4
1 8 2 5
2 9 3 6
C A D B
0 7 1 1 4
1 8 2 0 5
2 9 3 5 6
insert( )方法直接修改数据框本身
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加列、插入新列与删除列
第90页
(3)删除列
◼ ( )方法可以删除columns参数指定的一列或多列,该参数与rename( )方法的
类似,默认返回一个新的数据框。如果要删除数据框自身的列,则应将inplace参数设置为
True。例如:
df = ({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9], "D": [0, 0, 0]})
(columns=["C", "D"], inplace=True) # df自身删除两列
del df['A'] # 删除A列
df变化:
A B C D
0 1 4 7 0
1 2 5 8 0
2 3 6 9 0
A B
0 1 4
1 2 5
2 3 6
B
0 4
1 5
2 6
现在数据框仅
含一列数据
也可以使用del 命令删除一列或多列,但不能用 del
(labels=["C", "D"], axis=1, inplace=True)
也可以删除两列
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
调整列顺序
第91页
⚫ 数据框中的列是有序的,有2种方式可以调整其列序。
◼ 方式1。读取数据框df的某列保存到变量s(即用s引用它),然后从df中移除该列,最后
将s插入df中指定位置。这实际上就是将这列从df中取出来,然后插入指定位置。这种方
式适用于调整单列位置。例如,交换B、C两列的位置:
df = ({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9], "D": [0, 0, 0]})
s = df['C'] # 暂存C列
del df['C'] # 移除C列
(loc=1, column='C', value=s) # 插入C列
df变化:
A B C D
0 1 4 7 0
1 2 5 8 0
2 3 6 9 0
A B D
0 1 4 0
1 2 5 0
2 3 6 0
A C B D
0 1 7 4 0
1 2 8 5 0
2 3 9 6 0
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
调整列顺序
第92页
⚫ 数据框中的列是有序的,有2种方式可以调整其列序。
◼ 方式2。指定具有新顺序的列标签列表,然后从df中获取这些列并覆盖df。该方式适用于
调整多列。例如,将列序A-B-C-D调整为D-B-A-C:
df = ({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9], "D": [0, 0, 0]})
new_order = ['D', 'B', 'A', 'C'] # 指定新列序
df = df[new_order] # 按新列序读取各列,并覆盖df
df变化:
A B C D
0 1 4 7 0
1 2 5 8 0
2 3 6 9 0
D B A C
0 0 4 1 7
1 0 5 2 8
2 0 6 3 9
实际上是构造了一个新的数据框
可以通过在调序前后调用id(df)进行验证
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加行与删除行
第93页
⚫ ( )方法用于添加行,没有inplace参数,只能返回新数据框。
◼ 注意,添加的数据可以源自另一个数据框,也可以源自字典或Series,但此时ignore_index
参数必须设置为True,表示忽略行索引,从而自动添加新行的索引。
df1 = ([[1, 2], [3, 4]], columns=list('AB'))
df2 = ([[5, 6], [7, 8]], columns=list('AB'))
df3 = (df2) # 从另一个数据框中添加(相当于垂向合并两个结构相同的数据框)
df4 = (df2, ignore_index=True) # 忽略行索引
row_dict = {"A": 5, "B": 6}
df5 = (row_dict, ignore_index=True) # 忽略行索引时,可以从字典添加一行
row_series = ([5, 6], index=['A', 'B'])
df6 = (row_series, ignore_index=True) # 忽略行索引时,可以从Series添加一行
df1 df2 df3 df4 df5 df6
A B
0 1 2
1 3 4
A B
0 5 6
1 7 8
A B
0 1 2
1 3 4
0 5 6
1 7 8
A B
0 1 2
1 3 4
2 5 6
3 7 8
A B
0 1 2
1 3 4
2 5 6
A B
0 1 2
1 3 4
2 5 6
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加行与删除行
第94页
⚫ ( )方法用于添加行,没有inplace参数,只能返回新数据框。
◼ 每次调用append( )方法总是需要复制数据,并返回一个新的数据框,因此当多个数据框需
要拼接在一起时就会耗费更多的计算资源。
◼ 例如,有3个数据框df1~df3需要拼接在一起,执行df4=(df2)时,df1和df2中的
数据都被复制到新数据框df4,然后执行df=(df3)时,df3和df4中的数据也都被复
制到新数据框df中。因此,df1和df2中的数据相当于被复制了2次。
⚫ ( )方法可以将由多个数据框构成的列表沿着指定轴拼接为一个新数
据框,各数据框数据仅复制一次。
◼ 当参数axis=0时,表示在列上(纵向)拼接;当axis=1时,表示在行上(横向)拼接。
df1 df2
A B
0 1 2
1 3 4
A B
0 5 6
1 7 8
A B
0 1 2
1 3 4
2 5 6
3 7 8
多个数据框拼接时,建议使用concat( )方法,
而不是append( )方法
([df1, df2], axis=0, ignore_index=True)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加行与删除行
第95页
⚫ ( )方法用于删除指定标签对应的行或列。删除行时:
◼ 指定index参数为要删除的行的索引;
◼ 或使用labels参数指定行索引,且axis参数使用使用默认值0(1则表示对列操作)。
df df1 df2 df3
A B
0 1 2
1 3 4
2 5 6
3 7 8
A B
0 1 2
1 3 4
df = ([[1, 2], [3, 4], [5, 6], [7, 8]], columns=list('AB'))
df1 = (index=[2, 3])
df2 = (labels=[2, 3], axis=0)
df3 = (labels=['A'], axis=1)
A B
0 1 2
1 3 4
B
0 2
1 4
2 6
3 8
删除索引标签为A的列
删除整数位置索引为2和3的行
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
添加行与删除行
第96页
⚫ 如何删除满足条件的行?
◼ 首先,使用query( )方法查询满足条件的数据行,返回一个数据框;
◼ 然后,提取该数据框的行索引index对象;
◼ 最后,使用drop( )方法删除由这些行索引指定的行。
⚫ 例如,删除df中A列元素小于4的行:
df df4 idx df5
A B
0 1 2
1 3 4
2 5 6
3 7 8
A B
0 1 2
1 3 4
df = ([[1, 2], [3, 4], [5, 6], [7, 8]], columns=list('AB'))
df4 = ('A<4') # ① df中A列元素小于4的行
idx = # ② df中A列元素小于4的行所在的索引
df5 = (labels=idx, axis=0) # ③ 按指定行索引删除df中的行
Int64Index([0, 1], dtype='int64')
A B
2 5 6
3 7 8
或:df5 = (index=idx)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
按索引排序与按值排序
第97页
⚫ 数据框中的数据的排序支持两种方式:按索引排序和按值排序。
⚫ _index( )方法用于按行/列索引调整数据行/列的顺序。
◼ 参数axis = 0(默认值)时,数据行按行索引升序或降序排列;参数axis = 1时,数据列按
列索引升序或降序排列。
◼ 参数ascending用于指示是否升序排列,默认为True。
df df1 df2 df3
Name Sex Age
0 Tom M 35
1 Emily F 16
2 Fred M 28
Name Sex Age
0 Tom M 35
1 Emily F 16
2 Fred M 28
df = ({'Name': ['Tom', 'Emily', 'Fred'], 'Sex': ['M', 'F', 'M'], 'Age': [35, 16, 28]})
df1 = _index() # 默认按行索引升序排列数据行
df2 = _index(ascending=False) # 按行索引降序排列数据行
df3 = _index(axis=1) # 按列索引升序调整数据列的顺序
Name Sex Age
2 Fred M 28
1 Emily F 16
0 Tom M 35
Age Name Sex
0 35 Tom M
1 16 Emily F
2 28 Fred M
调整了列序调整了行序
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
按索引排序与按值排序
第98页
⚫ _values( )方法用于按元素值排序。
◼ 参数by是一个列表,用于指示按哪些列(或行)排序。
◼ 参数axis = 0(默认值)时,数据行按一个或多个列排序;
◼ 参数axis = 1时,数据列按一个或多个行排序。
◼ 参数ascending 指明排序方式是升序还是降序,各排序列/行可以单独指定。
df1 df2 df3 df4
Name Sex Age
0 Tom M 35
2 Fred M 28
1 Emily F 16
df1 = _values(by=['Name']) # 默认按Name列升序排列数据行
df2 = _values(by=['Name'], ascending=False) # 按Name列降序排列数据行
df3 = _values(by=['Sex', 'Age']) # 性别、年龄升序排列数据行
df4 = _values(by=['Sex', 'Age'], ascending=[True, False]) # 按性别升序、年龄降序排列数
据行
Name Sex Age
1 Emily F 16
2 Fred M 28
0 Tom M 35
Name Sex Age
1 Emily F 16
0 Tom M 35
2 Fred M 28
Name Sex Age
0 Tom M 35
1 Emily F 16
2 Fred M 28
Name Sex Age
1 Emily F 16
2 Fred M 28
0 Tom M 35
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
列值与行索引相互转换
第99页
⚫ _index( )方法用于将其某些列转换为行索引。
◼ 参数keys用于指定需要转换为索引的列。
◼ 参数append用于指定是否追加新索引。若为False(默认值),则替换当前的行索引(如
果存在);若为为True,则在当前的索引的基础上追加一级新索引。
◼ 若要修改数据框本身,则应将参数inplace设置为True。
◼ 例如,先将文件中的数据读入数据框,行索引默认为整数位置:
df = _csv("")
School Province Name Gender Birthdate Chinese Math English
0 文学院 山东 王琴 女 2002-05-26 95 105 137
1 文学院 江苏 吴文 男 2003-02-24 68 68 102
2 文学院 福建 盛红霞 男 2003-03-22 123 66 142
3 理学院 山东 张艳 女 2003-08-12 97 119 63
4 理学院 江苏 张冬 男 2001-03-31 137 88 122
5 理学院 福建 尤珊珊 女 2002-11-26 75 65 76
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
列值与行索引相互转换
第100页
◼ 将School列转换为行索引:
df1 = _index(keys='School') # School列转换为行索引
School Province Name Gender Birthdate Chinese Math English
0 文学院 山东 王琴 女 2002-05-26 95 105 137
1 文学院 江苏 吴文 男 2003-02-24 68 68 102
2 文学院 福建 盛红霞 男 2003-03-22 123 66 142
3 理学院 山东 张艳 女 2003-08-12 97 119 63
4 理学院 江苏 张冬 男 2001-03-31 137 88 122
5 理学院 福建 尤珊珊 女 2002-11-26 75 65 76
Province Name Gender Birthdate Chinese Math English
School
文学院 山东 王琴 女 2002-05-26 95 105 137
文学院 江苏 吴文 男 2003-02-24 68 68 102
文学院 福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
理学院 江苏 张冬 男 2001-03-31 137 88 122
理学院 福建 尤珊珊 女 2002-11-26 75 65 76
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
列值与行索引相互转换
第101页
◼ 将School列与Province列同时作为行索引:
df2 = _index(keys=['School', 'Province']) # School列和Province列转换为行索引
School Province Name Gender Birthdate Chinese Math English
0 文学院 山东 王琴 女 2002-05-26 95 105 137
1 文学院 江苏 吴文 男 2003-02-24 68 68 102
2 文学院 福建 盛红霞 男 2003-03-22 123 66 142
3 理学院 山东 张艳 女 2003-08-12 97 119 63
4 理学院 江苏 张冬 男 2001-03-31 137 88 122
5 理学院 福建 尤珊珊 女 2002-11-26 75 65 76
Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
第102页
⚫ _index( )方法可以把行索引转换为列值。
◼ 参数level可以指定被转换为列的级别(即行索引,默认所有级别)。
◼ 例如,将上例df2中的第0级索引School转换为列值:
df3 = _index(level='School') # School行索引转换为列值
Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
School Name Gender Birthdate Chinese Math English
Province
山东 文学院 王琴 女 2002-05-26 95 105 137
江苏 文学院 吴文 男 2003-02-24 68 68 102
福建 文学院 盛红霞 男 2003-03-22 123 66 142
山东 理学院 张艳 女 2003-08-12 97 119 63
江苏 理学院 张冬 男 2001-03-31 137 88 122
福建 理学院 尤珊珊 女 2002-11-26 75 65 76
第103页
⚫ _index( )方法可以把行索引转换为列值。
◼ 若只希望从行索引中删除某个级别,并不转换为列,则可以设置参数drop为True。
◼ 例如,如果将上例df2中的第0级索引School删除:
df4 = _index(level='School', drop=True) # 仅删除School索引
Name Gender Birthdate Chinese Math English
School Province
文学院 山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
理学院 山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
Name Gender Birthdate Chinese Math English
Province
山东 王琴 女 2002-05-26 95 105 137
江苏 吴文 男 2003-02-24 68 68 102
福建 盛红霞 男 2003-03-22 123 66 142
山东 张艳 女 2003-08-12 97 119 63
江苏 张冬 男 2001-03-31 137 88 122
福建 尤珊珊 女 2002-11-26 75 65 76
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
第104页
数据透视与数据融合
特点:数据从(垂向)长格式转换为(横向)宽格式
标识变量(id_vars)列
标识变量(id_vars)
度量变量(value_vars)
值(value)
变量(variable)列
值(value)列
⚫ 数据透视(pivot)的过程如图所示:
◼ 以左表Year列(即标识变量列)为行索引,按Course列(即变量列)来透视Earning列(即
值列)数据,得到右表。
◼ 左表Course列的不同取值作为右表中的列名(即3个度量变量)。
◼ 左表的同一年的Earning列中的3个值作为右表3个度量变量的值。
◼ 左表中在某个年份的不同课程的收入数据(对应多条记录),透视后在一个行中显示。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据透视与数据融合
⚫ (index, columns, values)方法用于实现数据透视功能。它将数据
从长格式转换为宽格式,返回一个透视数据框,不带聚合函数,可以处理文
本数据。
◼ index参数:用于指定行分组器,该列数据作为透视数据框的行索引。
◼ columns参数:用于指定列分组器,该列数据作为透视数据框的列索引(即度量变量列)
,该columns指定的列名同时会作为透视数据框的列索引名。
◼ values参数:用于指定需要透视数据列。可以指定一列或多列;该参数不指定时,表示包
含除index和columns列之外的所有列。
⚫ pivot( )方法构造透视数据框的流程:
◼ 根据index参数指定的列值,对记录行进行分组。
◼ 把columns指定的列的唯一值作为透视数据框列索引。
◼ 把一个分组中由values指定的列值,从垂向“旋转”为横向,作为透视数据框的一行,值
与列索引保持对应关系。
第105页
第106页
⚫ 例如,建立课程培训信息的数据框,并按每年的不同课程的收入进行透视。
data = [[2021, 'Python', 1000, 80],
[2021, 'Java', 2000, 140],
[2021, 'C++', 2500, 185],
[2022, 'Python', 1700, 93],
[2022, 'Java', 2100, 162],
[2022, 'C++', 2400, 205]]
df = (data=data, columns=['Year', 'Course', 'Earning', 'StudentNum'])
df1 = ( index='Year', # 指定作为新表的行索引的列
columns='Course', # 指定作为新表的列索引的列
values='Earning' # 指定作为新表的元素值的列
)
Year Course Earning StudentNum
0 2021 Python 1000 80
1 2021 Java 2000 140
2 2021 C++ 2500 185
3 2022 Python 1700 93
4 2022 Java 2100 162
5 2022 C++ 2400 205
Course C++ Java Python
Year
2021 2500 2000 1000
2022 2400 2100 1700
第107页
⚫ pivot( )方法的values参数一般只指定一列数据,但也可以指定多列数据。若不指定
values参数,就将剩余的列都当作元素值列,得到多级列索引。例如:
df2 = (index='Year', # 指定作为新表的行索引的列
columns='Course' # 指定作为新表的列索引的列
# values=['Earning', 'StudentNum']
)
Year Course Earning StudentNum
0 2021 Python 1000 80
1 2021 Java 2000 140
2 2021 C++ 2500 185
3 2022 Python 1700 93
4 2022 Java 2100 162
5 2022 C++ 2400 205
Earning StudentNum
Course C++ Java Python C++ Java Python
Year
2021 2500 2000 1000 185 140 80
2022 2400 2100 1700 205 162 93
具有两级列索引
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据透视与数据融合
⚫ 进行数据透视时,如果要对数据进行聚合操作(如:组内求和),则需要使
用pivot_table( )方法。该方法和pivot( )方法的功能相似,但是会对值进行聚合
操作,因此只能处理数值数据。
pivot_table(index, columns, values, aggfunc, fill_value)
◼ 前三个参数与pivot( )方法相同。
◼ aggfunc参数:用于指定聚合的函数,默认为'mean',可以是'sum'(或)等。
◼ fill_value参数:用于指定填充缺失值的值。
⚫ 例如,课程培训数据中,课程在同一年可能有多条记录,现在要按每年(
Year)的不同课程(Course)的收入进行数据透视,此时需要按年份求和。
data = [[2021, 'Python', 1000, 80], [2021, 'Java', 2000, 140], [2021, 'C++', 2500, 185],
[2021, 'Python', 600, 50], [2022, 'Python', 1700, 93], [2022, 'Java', 2100, 162],
[2022, 'C++', 2400, 205], [2022, 'Java', 700, 26]]
df = (data=data, columns=['Year', 'Course', 'Earning', 'StudentNum'])
第108页
第109页
df1 = _table(
index='Year', # 指定作为新表的行索引的列
columns='Course', # 指定作为新表的列索引的列
values='Earning', # 指定作为新表的元素值的列
aggfunc='sum' # 指定聚合函数,以进行组内求和
)
Year Course Earning StudentNum
0 2021 Python 1000 80
1 2021 Java 2000 140
2 2021 C++ 2500 185
3 2021 Python 600 50
4 2022 Python 1700 93
5 2022 Java 2100 162
6 2022 C++ 2400 205
7 2022 Java 700 26
Course C++ Java Python
Year
2021 2500 2000 1600
2022 2400 2800 1700
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
第110页
数据透视与数据融合
特点:数据从(横向)宽格式转换为(垂向)长格式
标识变量(id_vars)列
标识变量(id_vars) 度量变量(value_vars)
值(value)
变量(variable)列
值(value)列
⚫ 数据融合(也叫数据逆透视)(melt)的过程如图所示:
◼ 左表中选定若干标识变量列(这里为Year),它(们)作为融合数据框的标识变量列;
◼ 左表中的度量变量(Python、Java和C++列)列的索引标签,作为融合数据框中变量列(
命名为Course)的元素,而一年中各课程的收入数据将成为融合数据框的值列(命名为
Earning)的元素。
◼ 因此,原先在一行中的多列数据按课程名分裂成了多行,每行显示某年中一门课程的收
入。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据透视与数据融合
⚫ ( )方法用于实现融合数据功能。它将数据从宽格式转换为长格
式,返回一个融合数据框。
(id_vars, value_vars, var_name, value_name, col_level)
◼ id_vars参数:作为标识变量的列,可以是一列,也可以是多列。
◼ value_vars参数:作为值的列,也就是指定需要分裂的度量变量的索引列表。
◼ var_name参数:默认值是'variable',用于对长格式中度量变量的列名所在的列进行命名,
也就是列索引作为一列的值后,指定该列的索引(列名)。
◼ value_name参数:默认值是'value',用于对长格式中度量变量的列值所在的列进行命名,
也就是行中的值分裂到一列后,指定该列的索引(列名)。
◼ col_level参数:如果列有多级索引,则可以指定在哪一级索引上进行数据融合。
第111页
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据透视与数据融合
⚫ 例如,在图所示的数据融合中,调用melt( )方法时:
◼ id_vars对应的参数值为'Year'
◼ value_vars对应的参数值为['Python', 'Java', 'C++']
◼ var_name对应的参数值为'Course'
◼ value_name对应的参数值为'Earning'
第112页特点:数据从(横向)宽格式转换为(垂向)长格式
标识变量(id_vars)列
标识变量(id_vars) 度量变量(value_vars)
值(value)
变量(variable)列
值(value)列
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据透视与数据融合
data = [[2021, 1000, 2000, 2500], [2022, 1700, 2100, 2400]]
df = (data=data, columns=['Year', 'Python', 'Java', 'C++'])
df1 = (id_vars='Year', # 指定作为标识变量的列
value_vars=['Python', 'Java', 'C++'], # 指定需要分裂的度量变量的列索引集合
var_name='Course', # 指定度变量的名称构成的新列的索引(列名)
value_name='Earning' # 指定度变量的值构成的新列的索引(列名)
)
第113页特点:数据从(横向)宽格式转换为(垂向)长格式
标识变量(id_vars)列
标识变量(id_vars) 度量变量(value_vars)
值(value)
变量(variable)列
值(value)列
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
第114页
数据透视与数据融合
data = [[2021, 1000, 2000, 2500], [2022, 1700, 2100, 2400]]
df = (data=data, columns=['Year', 'Python', 'Java', 'C++'])
df1 = (id_vars='Year', # 指定作为标识变量的列
value_vars=['Python', 'Java', 'C++'], # 指定需要分裂的度量变量的列索引集合
var_name='Course', # 指定度变量的名称构成的新列的索引(列名)
value_name='Earning' # 指定度变量的值构成的新列的索引(列名)
)
Year Python Java C++
0 2021 1000 2000 2500
1 2022 1700 2100 2400
Year Course Earning
0 2021 Python 1000
1 2022 Python 1700
2 2021 Java 2000
3 2022 Java 2100
4 2021 C++ 2500
5 2022 C++ 2400
融合后,年份无序
数据融合
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
第115页
# 按Year列的值升序排列记录
_values(by='Year', inplace=True)
数据透视与数据融合
Year Python Java C++
0 2021 1000 2000 2500
1 2022 1700 2100 2400
Year Course Earning
0 2021 Python 1000
1 2022 Python 1700
2 2021 Java 2000
3 2022 Java 2100
4 2021 C++ 2500
5 2022 C++ 2400
Year Course Earning
0 2021 Python 1000
2 2021 Java 2000
4 2021 C++ 2500
1 2022 Python 1700
3 2022 Java 2100
5 2022 C++ 2400
排序后,整数位置索引
就无序了
排序
数据融合
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
第116页
# 重新设置行索引为有序的整数位置0,1,2,...
= range(0, len(df1))
数据透视与数据融合
Year Course Earning
0 2021 Python 1000
1 2022 Python 1700
2 2021 Java 2000
3 2022 Java 2100
4 2021 C++ 2500
5 2022 C++ 2400
Year Course Earning
0 2021 Python 1000
2 2021 Java 2000
4 2021 C++ 2500
1 2022 Python 1700
3 2022 Java 2100
5 2022 C++ 2400
Year Course Earning
0 2021 Python 1000
1 2021 Java 2000
2 2021 C++ 2500
3 2022 Python 1700
4 2022 Java 2100
5 2022 C++ 2400
排序
重置行索引
Year Python Java C++
0 2021 1000 2000 2500
1 2022 1700 2100 2400
数据融合
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
缺失值处理
⚫ Pandas使用NaN和NaT(Not a Time)表示缺失值(Missing Value),NaT专门
表示时间类型的缺失值。缺失值也叫空值,可记为NA(Not Available),
non-NA表示非空值。、和都是代表缺失值的符号常量。
⚫ 在数据框中,与NA相关的常用方法:
◼ where( ) :用于将不满足条件的元素设置为NA。
◼ isnull( )和notnull( ) :用于判断元素值是否为NA。
◼ count( ) :用于返回每行或每列的non-NA元素的个数。
◼ dropna( ) :用于删除包含NA元素的行或列。
◼ ffill( )、bfill( )和interpolate( ) :分别用NA元素之前的元素值、之后的元素值,或前后元素
的插值填充该NA元素。
◼ fillna( ) :用于将NA元素填充为value参数指定的值。
除了isnull( )、notnull( )和count( ) ,
其余的方法都有inplace参数,默认值为False
第117页
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
不满足条件的元素置空
第118页
⚫ where( )方法用于将不满足指定条件的元素设置为NA。
◼ 如果整数类型的列出现缺失值,则该列会被自动转换为浮点数类型。
◼ cond参数用于指定置空条件,传入一个二维布尔类数组。
⚫ 例如,将数据框中小于等于2的元素全部置为NA:
(0) # 固定随机数种子,这样每次运行程序产生的伪随机系列就是固定的
A = (0, 10, (10, 3))
df = (data=A, columns=['A', 'B', 'C'])
df1 = (df > 2) # 小于等于2的元素全部置为NaN,返回一个DataFrame
第119页
df df>2 df1
A B C
0 True False True
1 True True True
2 True True False
3 True True True
4 True True False
5 True True True
6 True False True
7 True True True
8 True True False
9 True True False
(0) # 固定随机数种子,这样每次运行程序产生的伪随机系列就是固定的
A = (0, 10, (10, 3))
df = (data=A, columns=['A', 'B', 'C'])
df1 = (df > 2) # 小于等于2的元素全部置为NaN,返回一个DataFrame
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6
6 8 NaN
7 9
8 4 NaN
9 3 NaN
A B C
0 5 0 3
1 3 7 9
2 3 5 2
3 4 7 6
4 8 8 1
5 6 7 7
6 8 1 5
7 9 8 9
8 4 3 0
9 3 5 0
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
判断元素是否为NA
第120页
⚫ isnull( )和notnull( )方法用于判断元素是否为NA,返回布尔型DataFrame对象。
df1 () ()
A B C
0 False True False
1 False False False
2 False False True
3 False False False
4 False False True
5 False False False
6 False True False
7 False False False
8 False False True
9 False False True
A B C
0 True False True
1 True True True
2 True True False
3 True True True
4 True True False
5 True True True
6 True False True
7 True True True
8 True True False
9 True True False
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6
6 8 NaN
7 9
8 4 NaN
9 3 NaN
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
统计non-NA元素的数量
第121页
⚫ count( )方法用于返回每行或每列的non-NA元素的个数,返回一个Series对象。
◼ 参数axis=0:在0轴上统计,即行与行之间统计,得到各列的非空元素数量;
◼ 参数axis=1:在1轴上统计,即各行内统计,得到各行的非空元素数量。
df1
# 各列non-NA元素个数
()
#各行non-NA元素个数
(axis=1))
A 10
B 8
C 6
dtype: int64
0 2
1 3
2 2
3 3
4 2
5 3
6 2
7 3
8 2
9 2
dtype: int64
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6
6 8 NaN
7 9
8 4 NaN
9 3 NaN
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
删除含有NA元素的列或行
第122页
⚫ dropna( )方法可以删除含有NA元素的行或列。
◼ 如果要删除含有NA的行,则axis参数需使用默认值0。
◼ 如果要删除含有NA的列,则需要指定axis参数为1。
◼ 如果使用thresh参数,则保留至少有thresh个 non-NA元素的行或列。
◼ how参数的取值:
'any'(默认值):表示出现任意NA就删除行或列;
'all':表示所有的值都是NA时才删除行或列。
◼ 如果inplace参数指定为True,则修改数据框本身。
◼ 当全部使用默认参数时,将删除包含NA的所有行。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
删除含有NA元素的列或行
第123页
⚫ dropna( )方法可以删除含有NA元素的行或列。
◼ 例如:
df1
# 删除包含NA的所有行
(axis=0)
# 保留至少含有7个non-NA的列
(axis=1, thresh=7)
A B C
1 3
3 4
5 6
7 9
A B
0 5 NaN
1 3
2 3
3 4
4 8
5 6
6 8 NaN
7 9
8 4
9 3
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6
6 8 NaN
7 9
8 4 NaN
9 3 NaN
A列有10个非空值;
B列有 8个非空值;
C列有 6个非空值。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
填充NA
第124页
⚫ 含有NA元素的行或列通常不能删除,因为删除行或列会导致其他非空元素也
被删除,而这些非空元素包含着有用信息。
⚫ 对于含有NA较少的行或列,更明智的做法是对NA元素进行填充。
⚫ 填充的方法有很多,常用的:
◼ ffill( )/bfill( ):用前/后元素填充;
◼ interpolate( ):插值填充;
◼ fillna( ):特殊值填充。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)用前/后元素填充
第125页
⚫ ffill( )和bfill( )方法分别使用NA元素的前一个和后一个元素填充NA元素。
◼ 注意,这里元素的前后顺序是由它们对应的整数位置大小确定的,小的在前,大的在后。
◼ 参数axis=0(行与行之间)表示在列上填充,axis=1(行内部)表示在行上填充。
df1
# 在列上填充
()
# 在行上填充
(axis=1)
# 在列上填充
()
A B C
0 5 NaN
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4
9 3
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6
6 8 NaN
7 9
8 4 NaN
9 3 NaN
A B C
0
1
2
3
4
5
6
7
8
9
A B C
0 5
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4 NaN
9 3 NaN
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)插值填充
第126页
⚫ interpolate( )方法用non_NA元素插值填充NA。
◼ 参数method用于指定插值方法:
参数值(字符串类型) 说明
linear(默认值)
忽略行索引,按等距线性插值。这是多级索引上唯一支持
的方法
time
按时间插值,此时索引为DateTime类型。该方法等价于将
时间转换为数值,然后以其作为自变量进行线性插值
index或values
使用索引的实际数值作为自变量进行线性插值(使用现有
点的值,或用左右各1个相邻的已知点插值)
pad 使用前一个现有值填充空值
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)插值填充
第127页
参数值(字符串类型) 说明
neares、zero、slinear、
quadratic、cubic、spline、
barycentric、 polynomial
调用SciPy库中interpolate模块的interp1d()函数完成插值。
这些参数(如nearest、zero、slinear等)使用索引的数值。
polynomial()和spline()函数都要求指定一个表示阶数的整型
参数order,例如5阶多项式进行插值:
(method='polynomial',order=5)
krogh、piecewise_polynomial、
spline、pchip、akima、
cubicspline
调用SciPy库中interpolate模块的对应函数完成插值,例如
使用krogh()函数实际调用的是
_interpolate()函数
from_devivatives
调用SciPy库中interpolate模块内BPoly的类的
from_devivitives()方法完成插值
⚫ interpolate( )方法用non_NA元素插值填充NA。
◼ 参数method用于指定插值方法:
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)插值填充
第128页
df1 df2 df3 df4 df5
A B C
0 5 NaN
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4
9 3
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6 NaN
6 8 NaN
7 9
8 4 NaN
9 3 NaN
B C
A
5 NaN
3
3 NaN
4
8 NaN
6 NaN
8 NaN
9
4 NaN
3 NaN
[5, 2] = # 修改元素值为NA
df2 = (method='linear') # 在0轴(列)上填充NA,按等距线性插值
df3 = _index(keys='A') # A列转换为行索引
df4 = (method='values') # 在0轴(列)上填充NA ,按行索引(index)线性插值
df5 = _index(level='A') # 将行索引重新转换为列
B C
A
5 NaN
3
3
4
8
6
8
9
4
3
A B C
0 5 NaN
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4
9 3
第129页
A B C
0 5 NaN
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4
9 3
0 h 2h
(0,7)
(2h,8)(h,)
0 h 2h
(0,6)
(3h,5)
(h,)
3h
(2h,)
df2 = (method='linear') # 在0轴(列)上填充NA,按等距线性插值
按等距插值 1 个点 按等距插值 2 个点
第130页
df4 = (method='values') # 在0轴(列)上填充NA ,按行索引线性插值
B C
A
5 NaN
3
3
4
8
6
8
9
4
3
C
1O 42 3 5 6 7 8 9 10
A
1
9
8
7
6
5
4
3
2
10
在A为 3, 8, 4, 3 这四处,存
在对应的已知点,直接使用
它们的 C 值填充;
在A=6 处的 C 值,用左右两
点(5, 3)与(8, 5)的线性插值填充
C列的插值情况
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(3)特殊值填充
第131页
⚫ NA也可以用所在列的均值(数值数据)或出现频次最高的元素(其所在列
的值域是一个有限个离散型数据的集合)填充,还可以用其他特殊值填充。
⚫ fillna( )方法用于将NA元素填充为value参数指定的特殊值。value参数若为字
典,则可以对各列指定不同的特殊值。
df1
# NA填充为-999
(value=-999)
# B列NA填充为-999,C列NA填充为C列均值
(value={'B': -999, 'C': ()})
A B C
0 5
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4
9 3
A B C
0 5 NaN
1 3
2 3 NaN
3 4
4 8 NaN
5 6
6 8 NaN
7 9
8 4 NaN
9 3 NaN
A B C
0 5
1 3
2 3
3 4
4 8
5 6
6 8
7 9
8 4
9 3
列均值为
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
删除重复数据
第132页
⚫ drop_duplicates( )方法用于删除数据框中重复的数据行。
◼ subset参数用于指示如何认定重复行。默认情况下两行中所有列都相同才算重复,但有
时,我们可以认为只要某些列重复了,就算记录重复。
◼ keep参数决定了如何保留重复行,其取值及含义:
'first'(默认值):重复的数据行中,保留第一行,其他的都删除。
'last':重复的数据行中,保留最后一行,其他的都删除。
False:删除所有的重复行。
◼ 如果想在数据框本省去重,则需将inplace参数设置为True。
与nlargest( ) 和nsmallest( )
方法中的keep参数相同
第133页
⚫ 例如,考虑一个关于拉面的简单数据集,它包含品牌(Brand)、风格(Style)和评
分(Rating)三列,现对该数据集去重。
df = ({'Brand': ['Yum Yum', 'Yum Yum', 'Indomie', 'Indomie', 'Indomie'],
'Style': ['cup', 'cup', 'cup', 'pack', 'pack'],
'Rating': [4, 4, , 15, 5]})
# 默认,删除所有列都重复的行,保留第一个重复行
df1 = _duplicates()
# 删除Brand列重复的行
df2 = _duplicates(subset=['Brand'])
# 删除brand列和style列都重复的行,并保留最后一个重复行
df3 = _duplicates(subset=['Brand', 'Style'], keep='last')
df1 df2 df3
Brand Style Rating
0 Yum Yum cup
1 Yum Yum cup
2 Indomie cup
3 Indomie pack
4 Indomie pack
Brand Style Rating
0 Yum Yum cup
2 Indomie cup
3 Indomie pack
4 Indomie pack
Brand Style Rating
0 Yum Yum cup
2 Indomie cup
Brand Style Rating
1 Yum Yum cup
2 Indomie cup
4 Indomie pack
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数值运算方法
第134页
⚫ Pandas支持加(+)、减(-)、乘(*)、除(/)、求余(%)等运算符
,其数据框或Series对象也提供add( )、sub( )、mul( )、div( )、mod( )等与二元
运算符对应的方法。例如:
A = [[1, 2, 3, 0],
[4, 5, 6, 0],
[7, 8, 9, 0]]
df = (data=A, columns=['A', 'B', 'C', 'D'])
A B C D
0 1 2 3 0
1 4 5 6 0
2 7 8 9 0
# 数据框加5,即所
有元素加5
df + 5
A B C D
0 6 7 8 5
1 9 10 11 5
2 12 13 14 5
0 6
1 9
2 12
Name: A, dtype: int64
0 3
1 9
2 15
dtype: int64
0 2
1 20
2 56
dtype: int64
#单列加5,即每个元素加5
+ 5
# 两列相加,即索引
相同的元素相加
+
# 两列相乘,即索引
相同的元素相乘
df['A'].mul()
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数值运算方法
第135页
⚫ 数据框或Series对象还提供了一些数值运算方法,例如max( )、min( )、mean( )
、sum( )、std( )等。
⚫ 这些方法都有如下3个常用参数:
◼ axis:用于指定运算对应的轴。 对于Series对象,axis只能取默认值0;对于数据框,默认
为0或'column',表示在列上运算,为1或'index'则表示在行上运算。
◼ level:用于指定运算对应的索引级别。
◼ skipna:用于指定运算是否自动跳过NA。
df
A B C D
0 1 2 3 0
1 4 5 6 0
2 7 8 9 0
A 12
B 15
C 18
D 0
dtype: int64
0 6
1 15
2 24
dtype: int64
# 默认在0轴(列)求和,
即行与行相加,到得各列上的和
()
# 在1轴(行)求和,
即行内元素相加,得到各行上的和
(axis=1)
第136页
A B C D
0 1 2 3 0
1 4 5 6 0
2 7 8 9 0
[[1, 2, 3, 0],
[4, 5, 6, 0],
[7, 8, 9, 0]]
0轴(即第1个维度)上
有3个“大元素”
第1个大元素:
[1, 2, 3, 0]
第2个大元素:
[4, 5, 6, 0]
第3个大元素:
[7, 8, 9, 0]
()
(axis=0)
即大元素求和:
[1, 2, 3, 0]
+
[4, 5, 6, 0]
+
[7, 8, 9, 0]
= [12, 15, 18, 0]
[ [1, 2, 3, 0] , [4, 5, 6, 0] , [7, 8, 9, 0] ]
0轴(即第1个维度)上有3个“大元素”
1轴(即第2个维度)上
有4个元素
1轴(即第2个维度)上
有4个元素
1轴(即第2个维度)上
有4个元素
(axis=1)
即各行内元素求和:
6
15
24
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
字符串数据处理
第137页
⚫ Pandas的str访问器是通过StringMethods类实现的,用于字符串处理:
◼ 提供了upper( )、capitalize( )、split( )、cat( )、replace( )、strip( )、find( )、match( )、
startswith( )、endswith( ) 、len( ) 等众多方法。
◼ str访问器可以被动态地附加到Series对象上,用于向量化(Vectorized)处理Series对象的
各字符串元素,并返回一个新的Series对象。
s1 s2 s3
0 PYTHON PROGRAMMING
1 THANK YOU!
2 我爱UPC
dtype: object
0 18
1 10
2 5
dtype: int64
0 [Python, Programming]
1 [thank, you!]
2 [我爱UPC]
dtype: object
s = (['Python Programming', 'thank you!', '我爱UPC'])
s1 = () # 每个元素转换为大写字母
s2 = () # 每个字符串的长度
s3 = (' ') # 每个元素分割成列表
0 Python Programming
1 thank you!
2 我爱UPC
dtype: object
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
字符串数据处理
第138页
⚫ str访问器也支持切片操作,例如[2:],表示获取一个由Series对象s中每个
字符串元素的从第3个字符开始的子串构成的Series对象。
s
0 Python Programming
1 thank you!
2 我爱UPC
dtype: object
0 ing
1 ou!
2 UPC
dtype: object
[-3:] # 每个元素取后3个字符
⚫ Series对象也支持字符串连接运算符(+)和字符串重复运算符(*)。
s + '$' # 每个元素末尾连接$符
0 Python Programming$
1 thank you!$
2 我爱UPC$
dtype: object
0 Python ProgrammingPython Programming
1 thank you!thank you!
2 我爱UPC我爱UPC
dtype: object
s * 2 # 字符串重复2遍
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
字符串数据处理
第139页
⚫ 由于Series对象支持通过布尔类数组选择元素,因此可以使用类似如下的方
式选择满足条件的字符串元素:
s7 s8 s9
0 False
1 False
2 True
dtype: bool
2 我爱UPC
dtype: object
0 Python Programming
1 thank you!
dtype: object
s7 = ('C') # 元素是否以字符C结尾
s8 = s[('C')] # 选出以字符C结尾的元素
s9 = s[('th')] # 选出含有th的字符串
0 Python Programming
1 thank you!
2 我爱UPC
dtype: object
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
字符串数据处理
第140页
⚫ 也可以在Series对象上使用map( )方法,它使用指定的函数作用到Series对象的
每个元素上,返回一个新的Series对象。
⚫ 调用map( )方法与使用str访问器的向量化方法方法作用相同,但是map( )方法
中的函数可以任意指定,既可以是系统提供的,也可以是自定义的。
s10 s11
0 Python programming
1 Thank you!
2 我爱upc
dtype: object
0 Python programming
1 Thank you!
2 我爱upc
dtype: object
# map()方法使自定义函数作作用到每个元素,使之首字母大写
s10 = (lambda x: ())
# 用()方法使每个元素的首字母大写
s11 = ()
0 Python Programming
1 thank you!
2 我爱UPC
dtype: object
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
字符串数据处理
第141页
⚫ 一个简单示例:
◼ 某采集的数据中,表示人口数量的字符串形式的数据含有千位分隔符(逗号)的要。现
在需要将其转换为数值,则在转换之前需要把逗号移除,否则将产生ValueError异常。
s df
0 86754
1 0
2 13254
3 13068161
Name: population, dtype: object
name population
0 Antigua and Barbuda 86754
1 Antarctica 0
2 Anguilla 13254
3 Angola 13068161
data = [['Antigua and Barbuda', '86,754'],
['Antarctica', '0'],
['Anguilla', '13,254'],
['Angola', '13,068,161']]
df = (data=data, columns=['name', 'population'])
s = df['population'].(',', '') # 替换字符串,去除逗号
df['population'] = () # 转换数据类型并更新列
name population
0 Antigua and Barbuda 86,754
1 Antarctica 0
2 Anguilla 13,254
3 Angola 13,068,161
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
关于DataFrame和Series对象的replace( )方法
第142页
replace(self, to_replace, value, inplace, limit, regex, method)
⚫ DataFrame和Series对象的replace方法可用于元素替换,元素类型可以是任意
的,该方法替换灵活。
◼ to_replace参数:需要被替换的元素,可以是标量(此时用value参数指定的值替换),或
是列表(value也是等长的列表),还可以是字典(不同的元素用不同的值替换,此时
value无效;DataFrame不同列中的特定值用value替换)。
◼ value参数:用于替换的值(标量、列表、或者None)
◼ regex参数:在字符串替换时,决定是否使用正则表达式。若使用正则表达式,则替换匹
配的子串;否则,只能替换整个字符串。
◼ method参数: {'pad', 'ffill', 'bfill', None},当to_replace参数是标量、列表或元组,且value参
数为None时,替换元素的方法。
第143页
>>> s = ([0, 1, 2, 3, 4])
>>> (0, 5)
0 5
1 1
2 2
3 3
4 4
dtype: int64
>>> df = ({'A': [0, 1, 2, 3, 4],
... 'B': [5, 6, 7, 8, 9],
... 'C': ['a', 'b', 'c', 'd', 'e']})
>>> (0, 5)
A B C
0 5 5 a
1 1 6 b
2 2 7 c
3 3 8 d
4 4 9 e
③ List-like `to_replace`
>>> ([0, 1, 2, 3], 4)
A B C
0 4 5 a
1 4 6 b
2 4 7 c
3 4 8 d
4 4 9 e
>>> df
A B C
0 0 5 a
1 1 6 b
2 2 7 c
3 3 8 d
4 4 9 e
② List-like `to_replace`
>>> ([0, 1, 2, 3], [4, 3, 2, 1])
A B C
0 4 5 a
1 3 6 b
2 2 7 c
3 1 8 d
4 4 9 e
第144页
>>> ({'A': 0, 'B': 5}, 100)
A B C
0 100 100 a
1 1 6 b
2 2 7 c
3 3 8 d
4 4 9 e
>>> df
A B C
0 0 5 a
1 1 6 b
2 2 7 c
3 3 8 d
4 4 9 e
③ dict-like `to_replace`
>>> ({'A': {0: 100, 4: 400}})
A B C
0 100 5 a
1 1 6 b
2 2 7 c
3 3 8 d
4 400 9 e
>>> ({0: 10, 1: 100})
A B C
0 10 5 a
1 100 6 b
2 2 7 c
3 3 8 d
4 4 9 e
第145页
(to_replace=r'^ba.$', value='new', regex=True)
④ Regular expression `to_replace`
(to_replace ={'A': r'^ba.$'}, value={'A': 'new'}, regex=True)
(regex=r'^ba.$', value='new')
A B
0 bat abc
1 foo bar
2 bait xyz
A B
0 new abc
1 foo new
2 bait xyz
A B
0 new abc
1 foo bar
2 bait xyz
A B
0 new abc
1 xyz new
2 bait xyz
(regex={r'^ba.$': 'new', 'foo': 'xyz'})
(regex=[r'^ba.$', 'foo'], value='new')
A B
0 new abc
1 foo new
2 bait xyz
A B
0 new abc
1 new new
2 bait xyz
A B
0 bat abc
1 foo bar
2 bait xyz
A B
0 --t abc
1 foo --r
2 --it xyz
(to_replace='ba', value='--')
(to_replace=r'ba', value='--', regex=True)
若使用RE,则替换匹配的子串;否则,只能替换整个字符串。
df = ({'A': ['bat', 'foo', 'bait'],
'B': ['abc', 'bar', 'xyz']})
第146页
⑤ Compare the behavior of ``({'a': None})`` and ``('a', None)``
to understand the peculiarities of the `to_replace` parameter
s = ([10, 'a', 'a', 'b', 'a'])
(to_replace={'a': None})
(to_replace={'a': None}, value=None, method=None)
0 10
1 None
2 None
3 b
4 None
dtype: object
(to_replace='a', value=None )
(to_replace='a', value=None, method='pad')
0 10
1 10
2 10
3 b
4 b
dtype: objectmethod: {'pad', 'ffill', 'bfill',None}, default ‘pad’
The method to use when for replacement, when `to_replace` is a
scalar, list or tuple and `value` is ``None``.
当value=None时,
method参数才有效,
且其默认值pad(垫片)
等同于ffill
0 10
1 a
2 a
3 b
4 a
dtype: object
第147页
一个字符串列替换的例子
地区,人口数量
北 京,21893095
天 津,13866009
河 北,74610235
山 西,34915616
内蒙古,24049155
辽 宁,42591407
吉 林,24073453
黑龙江,31850088
上 海,24870895
江 苏,84748016
浙 江,64567588
…
香 港,7500957
澳 门,683100
台 湾,23833611
使用pyechart包中的map模块绘图,省份、直辖市、
自治区、特别行政区名称需使用标准全称,例如:
台湾省、北京市、西藏自治区、香港特别行政区。
目前问题:名称简写且可能含有空白
第148页
data: = _csv('2020年中国各省人口.csv') # 读入数据
# ① 地区名移除空白,且后面统一加上’省‘
data['地区'].replace(to_replace=r'\s+', value='', regex=True, inplace=True)
data['地区'] = data['地区'] + '省'
# ② 根据不同的特殊值替换
special = {'北京省': '北京市', '天津省': '天津市', '上海省': '上海市', '重庆省': '重庆市', # 直辖市
'西藏省': '西藏自治区', '新疆省': '新疆维吾尔自治区', '内蒙古省': '内蒙古自治区', # 自治区
'宁夏省': '宁夏回族自治区', '广西省': '广西壮族自治区', # 自治区
'香港省': '香港特别行政区', '澳门省': '澳门特别行政区', # 特别行政区
}
data['地区'].replace(to_replace=special, inplace=True)
或: data['地区'] = data['地区'].map('{}省'.format)
使用正则表达式
替换匹配的子串
根据字典替换整个字符串
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
日期数据处理
第149页
⚫ _datetime( )函数用于将字符串形式的日期转换为日期时间类型,形如:
df['publish_time'] = _datetime(df['publish_time'], error='coerce')
⚫ 参数error用于指定转换失败的输出方式,支持类型如下:
◼ raise:无效解析将引发异常。
◼ coerce:无效解析将设置为NaT。
◼ ignore:无效解析将原样返回输入。
⚫ Pandas的dt访问器是通过CombinedDatetimelikeProperties类实现的,用于对日
期时间类型的数据进行操作,可被动态地附加到Series对象上:
◼ 常用于提取年、月、日、时、分、秒等数据,也能得到某个日期是一年中的第几天、一
年中的第几周、星期几等信息;
◼ 也提供对日期时间进行格式化(strftime( )方法)、转换为时间戳(to_timestamp( )方法)
等功能。
第150页
data = [['Fred', '1975-08-14'],
['Mark', '2001-11-05'],
['Rose', 'unknown']]
df = (data=data,
columns=['name', 'birthdate'])
# birthdate列转换为日期类型,错误转换将得到NaT
df['birthdate'] = _datetime(, errors='coerce')
df['year'] = df['birthdate'].(0).astype('int') # 转换提取年
df['month'] = df['birthdate'].(0).astype('int') # 转换提取月
df['day'] = df['birthdate'].(0).astype('int') # 转换提取天
df['Ym'] = df['year'].map(str) + '-' + df['month'].map(str) # 转换获取年-月
df['dayOfYear'] = df['birthdate'].(0).astype('int') # 一年中的第n天
df['weekOfYear'] = df['birthdate'].().(0).astype('int') # 一年中的第n周
df['weekday'] = df['birthdate'].(0).astype('int') # 周几, 一周里的第几天, Mon=0, Sun=6
NA不能转换为int,因此先
填充空值,再转换数据类型。
name birthdate
0 Fred 1975-08-14
1 Mark 2001-11-05
2 Rose unknown
name birthdate
0 Fred 1975-08-14
1 Mark 2001-11-05
2 Rose NaT
name birthdate year month day Ym dayOfYear weekOfYear weekday
0 Fred 1975-08-14 1975 8 14 1975-8 226 33 3
1 Mark 2001-11-05 2001 11 5 2001-11 309 45 0
2 Rose NaT 0 0 0 0-0 0 0 0
先转换为str类型,
然后拼接字符串
尝试替换为:df['birthdate'].('%Y-%m')
第151页
data = [['Fred', '1975-08-14'],
['Mark', '2001-11-05'],
['Rose', 'unknown']]
df = (data=data,
columns=['name', 'birthdate'])
# birthdate列转换为日期类型,错误转换将得到NaT
df['birthdate'] = _datetime(, errors='coerce')
# 为birthdate列NA填充特殊值
(value={'birthdate': '0000-00-00 00:00:00'}, inplace=True)
s_birthdate = df['birthdate'].astype('str') # 转换为字符串
df['Ym'] = [0:7] # 切片获取年-月,并作为新列加入数据框
df['year'] = [0:4] # 切片获取年,并作为新列加入数据框
df['month'] = [5:7] # 切片获取月,并作为新列加入数据框
df['day'] = [8:10] # 切片获取日,并作为新列加入数据框
name birthdate
0 Fred 1975-08-14
1 Mark 2001-11-05
2 Rose unknown
name birthdate
0 Fred 1975-08-14
1 Mark 2001-11-05
2 Rose NaT
name birthdate Ym year month day
0 Fred 1975-08-14 00:00:00 1975-08 1975 08 14
1 Mark 2001-11-05 00:00:00 2001-11 2001 11 05
2 Rose 0000-00-00 00:00:00 0000-00 0000 00 00
⚫ 获取时间的另一种方法,是将时间转换为字符串,然后通过切片获取子串。
0 1975-08-14 00:00:00
1 2001-11-05 00:00:00
2 0000-00-00 00:00:00
Name: birthdate, dtype: object
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
数据清洗基本流程及示例
第152页
⚫ Pandas 提供功能强大的类库,不管数据处于什么状态,它可以帮助我们通过
数据清洗,最后得到清晰明了的数据。
⚫ Pandas数据清洗一般流程如下:
(1)准备工作(导入pandas包、准备好要清洗的数据等)
(2)检查数据
(3)处理缺失数据(添加默认值、删除不完整的行或列等)
(4)删除重复数据
(5)规范化数据类型
(6)必要的转换(错别字、大小写不统一、数量单位不统一、输入了额外的空格等)
(7)将一列拆分为多列
(8)重命名列名
(9)保存结果(保存到文件或数据库)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
案例1—清洗影视数据
第153页
⚫ 本示例所使用的影视数据集 包含电影的很多数据,包括影
名、演员、导演、预算、总收入,以及IMDB评分和上映时间等。
记录数
5043
字段数
28
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)准备工作与检查数据
第154页
⚫ 导入pandas包,加载数据集,并观察部分数据。
import pandas as pd
df = _csv('') # 加载数据集
print(df)
color director_name ... aspect_ratio movie_facebook_likes
0 Color James Cameron ... 33000
1 Color Gore Verbinski ... 0
2 Color Sam Mendes ... 85000
3 Color Christopher Nolan ... 164000
4 NaN J. J. Abrams ... NaN 0
... ... ... ... ... ...
5038 Color Scott Smith ... NaN 84
5039 Color NaN ... 32000
5040 Color Benjamin Roberds ... NaN 16
5041 Color Daniel Hsia ... 660
5042 Color Jon Gunn ... 456
[5043 rows x 28 columns]
存在NA,有些列名冗长(例如
movie_facebook_likes)等
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)处理缺失值
第155页
⚫ 有些电影的country字段为NaN,可以使用空字符串或其他默认值(例如
None Given)进行填充。
print(().country)
# 空值处理:填充特定值
df['country'].fillna('', inplace=True)
# 或: ('', inplace=True)
# 或: = ('')
print(().country)
0 USA
1 USA
2 UK
3 USA
4 NaN
Name: country, dtype: object
0 USA
1 USA
2 UK
3 USA
4
Name: country, dtype: object
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)处理缺失值
第156页
⚫ 有些电影的duration列值为NaN,假定使用该列的平均值进行填充。
print((7).duration)
# 用平均值(取整)填充空值
df['duration'].fillna(int(()), inplace=True)
# 或: (int(()), inplace=True)
# 或: = (int(()))
print((7).duration)
0
1
2
3
4 NaN
5
6
Name: duration, dtype: float64
0
1
2
3
4
5
6
Name: duration, dtype: float64
默认NA不纳入统计
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)处理缺失值
第157页
⚫ 分别删除非空值少于5个的行和title_year列为空值的行。
print()
# 删除非空值少于5个的行
(thresh=5, inplace=True)
# 删除上映时间为nan的数据行
(subset=['title_year'], inplace=True)
print()
可以验证,非空值少于5个的行并不存在:
df[(axis=1) < 5] # 非空值少于5个的行
将返回一个空的数据框。
(5043, 28)
(4935, 28)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(3)删除重复数据
第158页
⚫ 电影名应该是唯一的,因此可以根据move_title列去重。
print()
# 根据move_title列去重
_duplicates(subset=['movie_title'], inplace=True)
print()
(4935, 28)
(4811, 28)
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)规范化数据类型
第159页
⚫ 当读取CSV文件中的title_year列的整数数字时,由于该列存在空值,因此该
列类型被pandas识别为浮点类型。
⚫ 前面已删除该列为空值的行,现在可以将该列转换为整型。
print(df['title_year'].dtype)
# title_year列转换为int64
df['title_year'] = df['title_year'].astype()
print(df['title_year'].dtype)
float64
int64
注意,NA不能转换为int
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(5)必要的转换
第160页
⚫ 人工录入的数据可能存在单位不统一、错别字、英文单词大小写不统一、输
入了额外的空格等情形,都需要进行一些必要的转换。
这个特殊字符,其实是一种空格,
在记事本等编辑器中不可见的。
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(5)必要的转换
第161页
⚫ 先将电影名首尾的空白删除。
print(df['movie_title'][0], len(df['movie_title'][0])) # 输出:AVATAR 7
print(df['movie_title'][0].endswith('\xa0')) # 输出:True
# 删除首尾空白(包括HTML转义字符 ;表示non-breaking space(不间断空格),
unicode编码为u'\xa0',也就是excel中每个影名末尾的繁体字“聽”)
df['movie_title'] = df['movie_title'].()
print(df['movie_title'][0], len(df['movie_title'][0])) # 输出:AVATAR 6
print(df['movie_title'][0].endswith('\xa0')) # 输出:False
⚫ 然后将电影名统一为大写形式。
print((2))
df['movie_title'] = df['movie_title'].() # movie_title 列改成大写
print((2))
0 Avatar
1 Pirates of the Caribbean: At World's End
Name: movie_title, dtype: object
0 AVATAR
1 PIRATES OF THE CARIBBEAN: AT WORLD'S END
Name: movie_title, dtype: object
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(6)重命名列
第162页
⚫ 某些数据列可能是由计算机生成的,因此列名有可能也是计算机按照一定规
律生成的。这些列名对我们阅读可能不够友好,因此需要重命名。
⚫ 这里将movie_facebook_likes列和 title_year列分别重命名为 facebook_likes和
facebook_likes。
print(df[['title_year', 'movie_facebook_likes']].head(2))
# 重命名列
(columns={'title_year': 'release_date', 'movie_facebook_likes': 'facebook_likes'},
inplace=True)
print(df[['release_date', 'facebook_likes']].head(2))
title_year movie_facebook_likes
0 2009 33000
1 2007 0
release_date facebook_likes
0 2009 33000
1 2007 0
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(7)保存结果
第163页
⚫ 数据清洗后通常要保存起来,以便后续进行处理。本例用_csv( )方法将
结果保存为CSV文件。
_csv('', header=True, index=False, encoding='utf-8')
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
案例2—清洗患者心率数据
第164页
⚫ 数据集记录了若干位患者在不同时段的心跳情况。
行数
11
列数
10
行号 姓名 年龄 体重
男患者在0:0~6:00、6:00~12:00和12:00~18:00的心率
女患者在3个不同时段的心率
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)准备工作与检查数据
第165页
⚫ 加载数据集,并观察数据。数据集中没有列名,因此在加载数据时指定。
names = ['name', 'age', 'weight', 'm0006', 'm0612', 'm1218', 'f0006', 'f0612', 'f1218']
df = _csv('',
usecols=range(1, 10), # 第1列不读取
names=names) # 数据中不包含列名,指定列索引
print(df)
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Huey McDuck 189lbs - - - 68 75 72
10 Louie McDuck 45kgs - - - 92 95 87
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)准备工作与检查数据
第166页
⚫ 观察数据集,容易发现一些问题。
① 姓名列应该拆分为FirstName和LastName两列。
② 体重列数据的单位不统一,包括kgs和lbs两种单位。
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Huey McDuck 189lbs - - - 68 75 72
10 Louie McDuck 45kgs - - - 92 95 87
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)准备工作与检查数据
第167页
⚫ 观察数据集,容易发现一些问题。
③ 存在缺失值,例如心率列和体重列。
④ 存在空白行和重复数据。
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Huey McDuck 189lbs - - - 68 75 72
10 Louie McDuck 45kgs - - - 92 95 87
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(1)准备工作与检查数据
第168页
⚫ 观察数据集,容易发现一些问题。
⑤ 用表格记录数据方便,但是不便于数据分析。不同时间段的心率在一行显示,应该进
行数据融合,也就是水平显示应改为垂直显示,一个患者对应3条记录。列名中性别与
时间段混在一起,也应该分开。
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Huey McDuck 189lbs - - - 68 75 72
10 Louie McDuck 45kgs - - - 92 95 87
第169页
⚫ 清洗的目标结果形如:
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 Huey McDuck 189lbs - - - 68 75 72
10 Louie McDuck 45kgs - - - 92 95 87
firstname lastname age weight pulse_rate sex hour
id
1 Dewey McDuck 19 56 71 f 00-06
2 Dewey McDuck 19 56 78 f 06-12
3 Dewey McDuck 19 56 75 f 12-18
4 Donald Duck 34 70 85 f 00-06
5 Donald Duck 34 70 84 f 06-12
6 Donald Duck 34 70 76 f 12-18
... ... ... ... ... ... ... ...
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(2)删除空白行和去除重复行
第170页
# 删除空白行
(how='all', inplace=True)
# 去重
_duplicates(inplace=True)
print(df)
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
10 Louie McDuck 45kgs - - - 92 95 87
行索引号为8和9的行
已被删除
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(3)拆分name列
第171页
⚫ 将name列拆成firstname和lastname两列,并删除name列。
# 拆分name列
df[['firstname', 'lastname']] = df['name'].(expand=True)
# 删除name列
('name', axis=1, inplace=True)
print(df)
age weight m0006 m0612 m1218 f0006 f0612 f1218 firstname lastname
0 70kgs 72 69 71 - - - Mickéy Mousé
1 - - - 85 84 76 Donald Duck
2 NaN - - - 65 69 72 Mini Mouse
3 NaN 78kgs 78 79 72 - - - Scrooge McDuck
4 - - - 69 NaN 75 Pink Panther
5 189lbs - - - 68 75 72 Huey McDuck
6 56kgs - - - 71 78 75 Dewey McDuck
7 78kgs 78 76 75 - - - Scööpy Doo
10 45kgs - - - 92 95 87 Louie McDuck
name age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71
1 Donald Duck
2 Mini Mouse
3 Scrooge McDuck NaN
4 Pink Panther
5 Huey McDuck 189lbs
6 Dewey McDuck 56kgs
7 Scööpy Doo 78kgs 78 76 75
10 Louie McDuck 45kgs
传入True, 返回一个DataFrame,包含两列;
否则,返回一个Series,元素是字符串列表
两个新列
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(3)拆分name列
第172页
⚫ 调整列序,使firstname和lastname列分别是第1和第2列。
s = # 暂存lastname列
del df['lastname'] # 从df中移除lastname列
(0, column='lastname', value=s) # lastname列作为第0列插入
s = # 暂存firstname列
del df['firstname'] # 从df中移除firstname列
(0, column='firstname', value=s) # firstname列作为第0列插入
print(df)
firstname lastname age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
10 Louie McDuck 45kgs - - - 92 95 87
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)统一列数据的单位
第173页
⚫ weight列的单位不统一,有的单位是 kgs(千克),有的单位是 lbs(磅)。将单位
统一为kgs,并将数字后的kgs去除,已知1kgs≈。有多种方法实现:
◼ 方法①:通过整数位置索引,遍历该列元素,以lbs结尾则转换单位。
◼ 方法②:遍历各行,判断标签索引为weight的元素,以lbs结尾则转换单位。
◼ 方法③:先找到数据框中所有weight字段以lbs结尾的行的index, 然后根据这些index定位
需要元素并转换单位。
firstname lastname age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70kgs 72 69 71 - - -
1 Donald Duck - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78kgs 78 79 72 - - -
4 Pink Panther - - - 69 NaN 75
5 Huey McDuck 189lbs - - - 68 75 72
6 Dewey McDuck 56kgs - - - 71 78 75
7 Scööpy Doo 78kgs 78 76 75 - - -
10 Louie McDuck 45kgs - - - 92 95 87
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)统一列数据的单位
第174页
◼ 方法①:通过整数位置索引,遍历该列元素,以lbs结尾则转换单位。
for i in range(len(df)):
if ([i, 3]) and [i, 3].endswith('lbs'):
# 转换单位
[i, 3] = f"{int(float([i, 3][0:-3])/)}kgs"
df['weight'] = df['weight'].str[0:-3] # 移除单位kgs
print(df)
firstname lastname age weight m0006 m0612 m1218 f0006 f0612 f1218
0 Mickéy Mousé 70 72 69 71 - - -
1 Donald Duck 70 - - - 85 84 76
2 Mini Mouse NaN - - - 65 69 72
3 Scrooge McDuck NaN 78 78 79 72 - - -
4 Pink Panther 90 - - - 69 NaN 75
5 Huey McDuck 85 - - - 68 75 72
6 Dewey McDuck 56 - - - 71 78 75
7 Scööpy Doo 78 78 76 75 - - -
10 Louie McDuck 45 - - - 92 95 87
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)统一列数据的单位
第175页
◼ 方法②:遍历各行,判断标签索引为weight的元素,以lbs结尾则转换单位。
for index, row in (): # 遍历各行对应的元组(index,Series)
if (row['weight']) and row['weight'].endswith('lbs'):
# 转换单位
[index, 'weight'] = f"{int(float(row['weight'][0:-3]) / )}kgs"
df['weight'] = df['weight'].str[0:-3] # 移除单位kgs
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)统一列数据的单位
第176页
◼ 方法③:先找到数据框中所有weight字段以lbs结尾的行的index, 然后根据这些index定位
需要元素并转换单位。
# 布尔型Series对象, Nan对应的测试值仍为Nan
rows_with_lbs = df['weight'].('lbs')
print(rows_with_lbs)
# Nan值填充为False
(False, inplace=True)
print(rows_with_lbs)
0 False
1 True
2 NaN
3 False
4 True
5 True
6 False
7 False
10 False
Name: weight, dtype: object
0 False
1 True
2 False
3 False
4 True
5 True
6 False
7 False
10 False
Name: weight, dtype: bool
信
息
时
代
学
习
方
法
系
列
讲
座
大数据采集与清洗
第
9
章
P
a
n
d
a
s
数
据
清
洗
(4)统一列数据的单位
第177页
# weight字段以lbs结尾的行有哪些?
print(df[rows_with_lbs])
0 False
1 True
2 False
3 False
4 True
5 True
6 False
7 False
10 False
Name: weight, dtype: bool
firstname lastname age weight m0006 m0612 m1218 f0006 f0612 f1218
1 Donald Duck - - - 85 84 76
4 Pink Panther