Pandas的I/O处理
在我们开始分享有关数据清洗、数据整理的相关实践代码前,我们先来看一下Pandas库中的文件读入与写出处理。这在Pandas库的知识分享中我们也曾专门提到过。这里权当是做一个温故而知新。在后面的很多实践示例以及实际的工作中,我们通常都要从文件、数据库等存储介质中获取大量的数据,或者是通过网络爬虫的手段从网络上获取大量数据。但实际上通过爬虫获取的数据也通常会被保存在文件或者数据库表中。因此,我们最终还是以文件、数据库等存储媒介作为Pandas的I/O操作对象。
假设我们现在有一张记录一个年级中多个班级内各自一部分学生的高三月考成绩的表单。现在我们需要对它做如下三个操作:
1、将表单中的数据读出来并显示到电脑屏幕上;
2、将表单中的数据从excel格式存储为txt格式,并输出txt格式下的成绩单;
3、将表单中的数据从excel格式存储为csv格式,并输出csv格式下的成绩单。
要求输出结果是整齐的,所存储的文件中,不得出现乱码。
现在我们就把实现以上三个操作并满足上面两个要求的代码实现如下:
from pandas import read_excel,read_table,read_csv
import pandas as pd
#下面两行代码通常用于设置显示格式的字段对齐
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
#利用read_excel()函数读取所保存的Excel表单中的第一张表:Sheet1
df = read_excel(r'E:\tmp\pandas\example1.xlsx',sheet_name='Sheet1')
print(df)
print(df.shape)
#以下三行代码用于展示如何把DataFrame数据存储为txt文档
#to_csv()函数中的index=False,表示保存的txt文档中不需要行索引
#但这里仍然需要注意的是保存的txt文件中内容会存在不对齐现象,尽管不太严重
#read_csv()读取txt文件时,需要用sep='\t'来强制显示对齐
df.to_csv(r'E:\tmp\pandas\example.txt',sep='\t',index=False)
df2 = read_csv(r'E:\tmp\pandas\example.txt',sep='\t')
print(df2)
print()#打印一个空行,以作结果区分
#以下三行代码用于展示如何把DataFrame数据存储为
#CSV文件,且利用参数encoding='utf_8_sig'消除保存文件中的中文乱码显示
#利用read_csv()中的sep参数值设置为英文的逗号,确保读出数据是严格对齐
df.to_csv(r'E:\tmp\pandas\example.csv',index=False,header=True,encoding="utf_8_sig")
df3 = read_csv(r'E:\tmp\pandas\example.csv',sep=',',encoding="utf_8_sig")
print(df3)
其输出结果如下:
关于Pandas的输入输出处理,大体上都可以按照这个套路来做,这在数据分析过程中尤其普遍,大家不妨多练习几遍。
2数据清洗—去重实践示例
我们在之前的数据清洗的理论知识分享部分已经提到过几种常见的数据清洗操作,现在我们就逐一来看一看如何开展真正的数据清洗工作。
首先,我们拿到数据之后需要先看看是否存在重复数据:
import pandas as pd
from pandas import read_excel
#首先导入工作人员辛辛苦苦所收集到的数据
df = read_excel(r'E:\tmp\pandas\example1.xlsx',sheet_name='Sheet1')
#第二步,我们判断一下是否有重复的数据行,记住,判断数据重复一定是某一行
#的每一列数据取值都与另一行的各列数据取值都相等,才被认为有重复的数据行
print(df.duplicated())
print(df.shape)
#存在重复行时,删除多余的重复行数据
print(df.drop_duplicates().shape)
其运行结果如下:
0 False
1 False
2 False
3 False
4 False
5 False
6 False
7 False
8 False
9 False
10 False
11 False
12 False
13 False
14 False
15 False
16 False
17 True
18 False
19 False
20 False
21 False
22 False
23 False
24 False
25 False
26 False
27 False
28 False
29 False
30 False
dtype: bool
(31, 12)
(30, 12)
从结果中,我们不难看出原始的数据集中存在着一行数据与另外一行数据重复,且是第18行(标红的那一行)与数据表中其他的数据行产生了重复。
此外,我们从数组的shape上也可以看出,在处理重复行之前,数组是31行,12列;处理完重复行数据之后,数组形状就变成了30行12列。这就说明我们已经成功地把原始数据中的重复行给丢弃了。
注意:不论数据集中存在多少个重复的行,最终被丢弃处理之后,永远都会留下一行数据。
最后,我们还可以对df.drop_duplicates()函数添加一些列的字段,表示在数据集的某列之上展开去重操作。但通常我们并不希望这么做,因为这与“重复”的内涵有些不符。
如果你非得被迫去这么做,其实也很简单:
df.drop_duplicates('姓名')
这里的姓名就是数据集中的列名。如此一来凡是存在着同名的学生数据就会被干掉。
3数据清洗—缺失值处理实践示例
处理缺失值时,我们首先要做的就是判断数据中是否存在缺失值。这个时候我们需要先瞜一眼数据的真实内容,看看有哪些不同寻常的值,然后再把这些不同寻常的异常值改变成Pandas库能够识别的NaN取值。最后我们再来对这些被标记为NaN的数据字段作进一步的数值填充处理或者是直接丢弃有NaN标记的数据行。
PS:如果你所得到的数据中已经把一些不同寻常的值标记成了NaN,则只需要对NaN的值做缺失值处理即可。
请看下面这段小程序:
import pandas as pd
import numpy as np
from pandas import read_excel
#首先导入工作人员辛辛苦苦所收集到的数据
df = read_excel(r'E:\tmp\pandas\example1.xlsx',sheet_name='Sheet1')
#先查看数据的前5行
print(df.head())
#通过查看前5行数据可知其中有些诸如“作弊”、“缺考”之类的异常值
#将其标记成NaN,要特别注意,进行替换之后需要将新的DataFrame对象
#赋值给某个DataFrame变量,比如下面的处理,缺少赋值操作,则会表现得
#像是没有处理过一样,一位replace()操作是在原始的DataFrame对象的副本上操作的
#并不会影响到DataFrame对象本身的内容。
df=df.replace('作弊',np.nan)
df=df.replace('缺考',np.nan)
print(df.head())
#接下来我们就判断一下是否有NaN的数据出现,其实这一步可省略,但
#考虑到有时我们获得的数据已经是被特别处理过,里边已经把所有的
#异常值变成了NaN(如果存在异常值的话),故而我们这里还是把判断
#是否存在NaN的取值的操作放在这里
print(df.isnull().head())#也可以用df.notnull()来判断是否有缺失值
#判断出存在缺失值后,就多种方法来处理缺失值
#第一种方法,直接丢弃含有缺失值的数据行
#df.dropna()函数还可以指定参数:how,axis
#how=any,表示只有一行或一列数据全为0才会丢弃它
#axis=0,表示从行上处理缺失值;axis=1,表示从列上处理缺失值
print(df.dropna().head())
#第二种方法:用任意数值填充NaN值
print(df.fillna('?').head())
#第三种方法:用缺失值所在列的上一个数据来替换它
print(df.fillna(method='pad').head())
#第三种方法:用缺失值所在列的后一个数据来替换它
print(df.fillna(method='bfill').head())
#第四种方法:用缺失值所在列的平均值来替换它
print(df.fillna(df.mean()).head())
#第五种方法:指定某一列的平均值来替换它
#注意:这种方法一次只能修改一列的NaN值
print(df.fillna(df.mean()['语文':'英语']).head())
#第六种方法:指定某个值来取代某一列的NaN,可以操作多列
print(df.fillna({'语文':60,'物理':50}).head())
得到的运行结果如下:
PS:False表示该列的值不为NaN;True表示该列的值被标记为NaN。
以上就是常见的几种缺失值的处理操作及其结果示意截图。 此外,我们往往要对数值中的空格或者一些特定字符进行删除。 这个时候我们可以这么做:import pandas as pd
from pandas import DataFrame
from pandas import Series
df = DataFrame({'num':Series([1,23,4,55,6]),
'str':Series(['abc','def ',' ghik','ooo'])})
#先查看初始数据
print(df)
#删除列名为str的这一列中的数值内的空格字符
print(df['str'].str.strip())
#删除列名为str的这一列中的数值内的左侧空格字符
print(df['str'].str.lstrip())
#删除列名为str的这一列中的数值内的右侧空格字符
print(df['str'].str.rstrip())
#删除列名为str的这一列中的数值内的字符:k
print(df['str'].str.strip('k'))
其运行结果如下:
4总结
OK,本节主要给大家分享一些具体的数据清洗的操作示范。大家尤其需要注意的就是如何把一些异常值转换成NaN以及针对NaN数值的常见处理。
要特别说明的是,在最新版本的Pandas库中,我们这里所列举的一些API并没有使用到新版Pandas库中相同API中的全部参数,而只是使用了一些最常用到的参数。这一点大家务必要多加注意。以免今后看到官方给出的API参数说明时发现官方给出的参数那么多,而我们这里却只显示了一两个参数的使用,从而造成误解。
本节的分享就暂且到此为止,谢谢大家!我们下一节的分享中,不见不散!