数据清洗和准备

1. 前言

这是我在学习这是我在学习《利用Python进行数据分析》第七章的记录。

在数据分析和建模过程中,相当多时间要用到数据处理上:加载、处理、转换以及重塑。这些工作会占到分析师时间但80%或更多。有时,存储在文件和数据库中的数据的格式不适合某个特定的任务。

2. 处理缺失数据

缺失数据式时常发生的,pandas地目标直以就是你两轻松地处理缺失数据。对于数值数据,pandas用浮点值NaN(Not a Number)表示缺失数据。我们称之为哨兵值,方便检测。

1
2
string_data = pd.Series(['aardvark', 'artichoke', np.nan, 'avocado'])
string_data.isnull()

在pandas中,我们采用了R语言中的惯用法,即将缺失值表示为NA,它表示。在统计应用中,NA数据可能是不存在的数据或者虽然存在,但是没有观察到。

Python内置的None值在对象数组中也可以作为NA。

image-20201012185055245
image-20201012185055245
滤除缺失数据

dropna返回一个仅含非空数据和索引值的Series。

1
2
3
from numpy import nan as NA
data = pd.Sereis([1, NA, 3.5, NA, 7])
data.dropna()

对于DataFrame对象,可以丢弃全NA或含有NA的行或列。

how='all'将只丢弃全为NA的那些行。

axis=1可以丢弃列。

thresh=2可以只丢弃该列上为异常值的数据。

填充缺失数据

有时不像滤除缺失数据,而是希望通过其他方式填补空洞。fillna方法式最主要的函数。

df.fillna(0)就可以将异常值填补成0.

若是通过字典调用fillna,就可以事项对不同的列填充不同的值。

inplace=True其实fillna默认会返回新对象,但也可以对现有对象进行就地修改。

method可以利用插值的类似的方法。

data.fillna(data.mean())只要有些创新,可以利用fillna实现别的功能,比如可以传入Series的平均值或中位数。

image-20201012193102165
image-20201012193102165

3. 数据转换

移除重复数据

DataFrame中出现重复行有多种原因。比如用循环生成DataFrame。

duplicated方法返回一个布尔型Series,表明各行是否是重复出现的行。

drop_duplicates方法,会返回一个DataFrame,重复的数组标记为False。

data.drop_duplicates(['k1'])可以只根据k1列过滤重复项。

keep='last'保留最后一个。

利用函数或映射进行数据转换

map方法可以接受一个函数或含有映射关系的字典型对象。

1
data['food'].map(lambda x:meat_to_animal[x.lower()])

使用map是一种实现元素级转换以及其他数据清理工作的便捷方式。

替换值

fillna填充缺失数据可以看成值替换的一种特殊情况。map可用于修改对象的数据子集,而replace则提供了一种实现该功能的更简单、更灵活的方式。

1
data.replace([-999, -1000], np.nan)

传入的参数也可以是字典。

1
data.replace({-999:np.nan, -1000:0})
重命名轴索引

轴标签也可以通过函数或映射进行转换。

1
2
transform = lambda x:x[:4].upper()
data.index.map(transform)

可以将其赋值给index,就可以对DataFrame进行就地修改。

1
data.index = data.index.map(transform)

如果想要创建数据集的转换版,比较实用的方法是rename

1
data.rename(index=str.title, columns=str.upper)

注意:rename也可以结合字典型对象实现对部分轴标签的更新。

inplace=True可以实现就地修改。

离散化和面元划分

为了便于分析,连续数据常常被离散化或拆分成“面元”(bin). 假设有一组人员数据,将其划分为不同年龄组。

1
2
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)

cats是一个特殊的Categorical对象。它的地城含有一个表示不同分类名称的类型数组,以及一个codes属性中的年龄数据的标签

cats.code可以看到分类。

cats.categories可以看到几个categories。

pd.value_counts(cats)可以看到面元计数。

right=False可以改变区间开闭方向。

labels可以设置自己的面元名称。

precision=2可以限定小数位数。

1
pd.cut(data, 4, precision=2)

输入面元数量可以给出等长面元。

qcut是类似于cut的函数,根据样本分位数对数据进行面元划分。

检测和过滤异常值

过滤或变换异常值很大程度上就是运用数组运算。

1
data[np.abs(data) > 3] = np.sign(data) * 3
排列和随机采样
1
2
sampler = np.random.permutation(5)
df.take(sampler)

如果不想用替换的方式随机选取随机子集,可以在Series和DataFrame实用sample方法。

1
df.sample(n=3)

replace=True替换的方式。

计算指标/哑变量

一种常用于统计建模或机器学习的转换方式是:将分类变量转换成“哑变量”或“指标矩阵”。

如果DataFrame某一列中含有k个不同的值,则可以派生出一个k列矩阵或DataFrame(其值权威1或0).

pd.get_dummies(df['key'])

prefix可以给列加上一个前缀。

join方法可以合并矩阵。

结合get_dummiescut之类的离散化函数很有用。

1
2
3
4
np.random.seed(12345)
values = np.random.rand(10)
bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
pd.get_dummies(pd.cut(values, bins))

4. 字符串操作

字符串对象方法

split可以拆分字符串。

strip方法可以去掉空白符。

+可以将字符串组合。

join可以传入一个列表或元组,用前面的进行分割。

in 关键字检测字串。

indexfind可以找到索引,两者区别是找不到的话index会引发一场。

count可以返回指定字串的出现次数。

replace可以将指定模式替换成另一个模式

image-20201012205139987
image-20201012205139987
image-20201012205148571
image-20201012205148571

casefold将字符转换为小写,并将任何特定区域的变量字符组合准换成一个通用的可比较形式。

正则表达式

re模块的函数可以分为三个大类:模式匹配、替换以及拆分。

re.split('\s+',text)正则表达式先被编译,再在text上调用其split方法。

regex = re.compile('\s+')可以得到一个可重用的regex对象。

regex.findall(text)匹配所有模式。

search只返回第一个匹配项。

match只匹配字符串的首部。

sub可以替换。

注意:如果不仅想找出电子邮件地址,还想拆分,用圆括号包起来即可。

groups方法可以返回由模式各段组成的元组。

image-20201012210245707
image-20201012210245707
pandas的矢量化字符串函数

str.contarins方法可以检查各个地址是否含有”gmail”。

str.findall方法等,可以使用正则表达式。

str.get可以实现矢量化的元素获取操作,或者在str属性上使用索引。

1
2
matches.str.get(1)
matches.str[0]
image-20201012210615819
image-20201012210615819