在进行数据分析和建模的过程中,数据的清洗和准备是后续工作能够顺利开展的保障,包括数据加载、清理、转换和重新排列,可能占分析师80%以上的时间。数据清洗的过程中需要掌握对缺失值、重复值、字符串的操作,并掌握其他分析数据转换的工具。
处理缺失值
缺失数据在很多数据分析应用中出现,当清洗数据用于分析时,对缺失数据进行分析以确定数据收集问题或数据丢失导致的数据偏差通常也很重要。
pandas中对缺失值的处理方法归纳如下:
函数名 | 描述 |
---|---|
dropna | 根据参数丢弃缺失值所在的行/列 |
fillna | 用某些值填充缺失的数据或插值(如:’ffill’或’bfill’) |
isnull | 返回表明哪些值是缺失值 |
notnull | isnull的反函数 |
过滤缺失值
过滤缺失值的方法有很多种,常用的如下:
使用
pd.isnull
和布尔值索引
过滤缺失值1
2
3
4
5
6import numpy as np
import pandas as pd
data = pd.Series([1, np.nan, 3.5, np.nan, 7])
cleaned = data[data.notnull()]
print(cleaned)使用
pd.dropna
过滤缺失值1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import numpy as np
import pandas as pd
data = pd.DataFrame([[1., 6.5, 3.], [1., np.nan, np.nan], [
np.nan, np.nan, np.nan], [np.nan, 6.5, 3.]])
# 默认删除包含NA值的行
cleaned = data.dropna()
print(cleaned)
# 删除所有值都是NA的行
cleaned = data.dropna(how='all')
print(cleaned)
# 删除包含NA的列
cleaned = data.dropna(axis=1,how='all')
print(cleaned)
# 删除NA值,剩余数值的数量大于等于n
cleaned = data.dropna(thresh=1)
print(cleaned)
补全缺失值
主要使用fillna
方法补全缺失值
1 | import numpy as np |
fillna
函数参数整理:
参数 | 描述 |
---|---|
value | 标量值或字典对象,用于填充缺失值 |
method | 插值方法,默认是’ffill’ |
axis | 填充的轴,默认是axis=0 |
inplace | 修改被调用的对象,默认是False |
limit | 用于前向或后向填充时,最大的填充范围 |
数据转换
数据转换是数据过滤、清洗中的重要操作。
删除重复值
duplicated
方法返回一个布尔值Series
,反映每个行是否存在重复,drop_duplicates
方法返回DataFrame
,内容是duplicated
方法返回数组中的False
部分
1 | import numpy as np |
使用函数或映射进行数据转换
基于DataFrame
中的数组、列或列中的数值进行一些转换,可以利用map
函数
1 | # 给每种水果加上分类数据 |
替代值
当数据中包含异常值,如数值偏离大部分其他数据,为方便数据分析,可以使用replace
函数将异常值替换成其他正常值或空值。
1 | import numpy as np |
重命名轴索引
数据清洗过程中可能需要对轴标签进行转换,轴索引也有一个map
方法
1 | import numpy as np |
离散化和分箱
连续值经常需要离散化,或者分离成“箱子”进行分析。
假设有某项研究中的一组人群数据,需要将他们进行分组,放入离散的年龄框中,为实现这个,可以使用cut
函数
1 | import numpy as np |
检测和过滤异常值
过滤和转换异常值可以使用any
函数
1 | import numpy as np |
置换和随机抽样
置换可使用np.random.permutation
对DataFrame中的Series或行进行操作(随机重排序)。利用np.random.permutation
生成的随机数组要与想要排序的轴长度相等。
1 | import numpy as np |
计算指标/虚拟变量
将分类变量转换为“虚拟”或“指标”矩阵是一种用于统计建模或机器学习的转换操作。如果DataFrame
中的一列有k个不同的值,则可以衍生出一个k列的值为0和1的矩阵,利用get_dummies
函数实现这个功能。
1 | import numpy as np |
将get_dummies
与cut
等离散化函数结合使用时统计应用等一个常用办法:
1 | import numpy as np |
字符串操作
字符串对象的内建方法使得大部分文本操作非常简单。pandas允许将字符串和正则表达式简洁地应用到整个数据数组上,此外还能处理数据缺失带来的困扰。
字符串对象方法
很多字符串处理和脚本应用中,内建的字符串方法是足够的:
- 一个逗号分隔的字符串可以使用
split
方法拆成多块 split
常和strip
一起使用,用于清除空格和换行符- 字符串可以使用加号连接在一起,但着并不是一个通用方法。在字符串’::’的
join
方法中传入一个列表或元组是一种更快速且更加Pythonic的方法 - 使用Python的
in
关键字检测子字符串的最佳方法 index
在字符串没有找到是会抛出异常,而find
则返回-1count
返回某个特定子字符串在字符串中出现的次数replace
用一种模式替代另一种模式,通常也可以传入空字符串来删除某个模式
Python内建字符串方法汇总:
函数名 | 描述 |
---|---|
count | 返回子字符串在字符串中非重叠出现次数 |
endswith | 如果字符串以后缀结尾则返回True |
startswith | 如果字符串以前缀开始则返回True |
join | 使用字符串作为间隔符,用于粘合其他字符串 |
index | 如果在字符串中找到,则返回子字符串中第一个字符的位置;如果找不到则引发ValueError |
find | 如果在字符串中找到,则返回子字符串中第一个字符的位置;如果找不到则返回-1 |
rfind | 如果在字符串中找到,则返回子字符串中第一个字符最后出现的位置;如果找不到则返回-1 |
replace | 使用一个字符串替代另一个字符串 |
strip, strip, lstrip | 修剪空白,包括换行符;相当于对每个元素进行x.strip() |
split | 使用分隔符将字符串拆分为子字符串的列表 |
lower | 将大写字母转换为小写字母 |
upper | 将小写字母转换为大写字母 |
casefold | 将字符转换为小写,并将任何特定于区域的变量字符组合转换为常见的可比较形式 |
ljust, rjust | 左对齐或右对齐;用空格(其他字符)填充字符串的相反侧,以返回具有最小宽度的字符串 |
正则表达式
正则表达式
提供了一种在文本中灵活查找或匹配字符串模式的方法。Python中内建的re
模块是用于将正则表达式
应用到字符串上的库。re
模块主要有三个主题:模式匹配、替代、拆分
1 | import numpy as np |
正则表达式的方法如下:
函数名 | 描述 |
---|---|
findall | 将字符串中所有的非重叠匹配模式以列表形式返回 |
finditer | 与findall类似,但返回的是迭代器 |
match | 在字符串起始位置匹配,也可以将模式组建匹配到分组中;如果模式匹配上了,返回一个匹配对象,否则返回None |
search | 扫描字符串的匹配模式,如果扫描到了返回匹配对象,与match方法不同的是,search方法的匹配可以是字符串的任意位置,而不仅仅是字符串开头 |
split | 根据模式,将字符串拆分为多个部分 |
sub, subn | 用替换表达式替换字符串中所有的匹配(sub)或第n个出现的匹配串(subn) |
正则表达式模式字符串使用特殊的语法来表示一个正则表达式:
字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。
多数字母和数字前加一个反斜杠时会拥有不同的含义。
标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
反斜杠本身需要使用反斜杠转义。
由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r’\t’,等价于 ‘\t’)匹配相应的特殊字符。
下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[…] | 用来表示一组字符,单独列出:[amk] 匹配 ‘a’,’m’或’k’ |
[^…] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{ n} | 精确匹配 n 个前面表达式。例如, o{2} 不能匹配 “Bob” 中的 “o”,但是能匹配 “food” 中的两个 o。 |
re{ n,} | 匹配 n 个前面表达式。例如, o{2,} 不能匹配”Bob”中的”o”,但能匹配 “foooood”中的所有 o。”o{1,}” 等价于 “o+”。”o{0,}” 则等价于 “o*”。 |
re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
a| b | 匹配a或b |
(re) | 对正则表达式分组并记住匹配的文本 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (…), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#…) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配字母数字及下划线 |
\W | 匹配非字母数字及下划线 |
\s | 匹配任意空白字符,等价于 **[ \t\n\r\f]**。 |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]. |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
\1…\9 | 匹配第n个分组的内容。 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
向量化字符串函数
清理杂乱的数据集用于分析时,通常需要大量的字符串处理和正则化,可以使用pd.map方法将字符串和有效的正则表达式方法应用到每个值上,但是在NA值上会失败,为了解决这个问题,Series有面向数组的方法用于跳过NA值的字符串操作
1 | import numpy as np |
部分向量化字符串方法的列表:
函数名 | 描述 |
---|---|
cat | 根据可选的分隔符按元素黏合字符串 |
contains | 返回是否含有某个模式/正则表达式的布尔值数组 |
count | 模式出现次数的计数 |
extract | 使用正则表达式从字符串Series中分组抽取一个或多个字符串;返回的结果是每个分组形成一列的DataFrame |
endswith | 等价于对每个元素使用x.endwith(模式) |
startswith | 等价于对每个元素使用x.startwith(模式) |
findall | 找出字符串中所有的模式/正则表达式匹配项,以列表返回 |
get | 对每个元素进行索引(获得第i个元素) |
isalnum | 等价于内建的str.alnum |
isalhpa | 等价于内建的str.isalhpa |
isdecimal | 等价于内建的str.isdecimal |
isdigit | 等价于内建的str.isdigit |
islower | 等价于内建的str.islower |
isnumeric | 等价于内建的str.isnumeric |
isupper | 等价于内建的str.isupper |
join | 根据传递的分隔符,将Series中的字符串联合 |
len | 计算每个字符串的长度 |
lower, upper | 转换大小写;等价于对每个元素进行x.lower()/x.upper() |
match | 使用re.match将正则表达式应用到每个元素上,将匹配分组以列表形式返回 |
pad | 将空白加到字符串的左边、右边或两边 |
center | 等价于pad(side=’both’) |
repeat | 重复值(例如s.str.repeat(3)等价于对每个字符串进行x*3) |
replace | 以其他字符串替代模式/正则表达式的匹配项 |
slice | 对Series中的字符串进行切片 |
split | 以分隔符或正则表达式对字符串进行拆分 |
strip | 对字符串两边空白进行消除,包括换行符 |
rstrip | 消除字符串右边的空白 |
lstrip | 消除字符串左边的空白 |
关于正则表达式的其他基础学习可以查看菜鸟教程-正则表达式。