当前位置 : 首页 » 博文聚焦 » 正文

用pandas清洗数据具体步骤(基础篇一)

分类 : 博文聚焦 | 发布时间 : 2018-01-15 18:30:38 | 浏览 : 307

引言

     数据清洗是一项复杂且繁琐(kubi)的工作,同时也是整个数据分析过程中最为重要的环节。但在实际的工作中一个分析项目70%左右的时间花在清洗数据上面。数据清洗的目的有两个,第一是通过清洗让数据可用。第二是让数据变的更适合进行后续的分析工作。换句话说就是有”脏”数据要洗,干净的数据也要洗。本篇文章将用一个简单的范例来介绍使用pandas进行数据清洗的流程。

读取数据

      pandas模块中有专门针对xlsx和xls这类excel文件的读取方法read_excel。当然用的最多的还是read_csv文件。因为excel文件最多只能存储100多万行,但是csv文件可以存储上亿行数据。既然是简单范例,我就只使用execl来读取了。

tt=pd.read_excel(r'd:\\000030.xlsx',sheet_name='Sheet1')
#直接读取硬盘中的excel文件,变成Dataframe格式 
表格格式如下图所示:


从表格中可以看出,第一存在很多空值;第二还有很多亿元,万元等字符串影响了进行算术运算。第一步我们首先要处理空值:

处理空值

这里涉及到对空值的处理:1删除2替换3填充

删除又分为是每行有一个空格就删除该行还是有三个空值就删除该行;

替换可以用上下行的值替换或者是用平均值替换

print (tt.isnull().any())   # 这是按照列统计的空值
print (tt[tt.isnull().values==True]) #查看哪些值是空值

# 这里涉及到对空值的处理:删除还是替换然后还有填充(这里删除分为有一个空值删除还是有两个空值删除一行。替换可以用特定值替换或者是用平均值替换)
tt.fillna(0,inplace=True)  # 根据本例的特点,空值可以填充0

对行索引和列索引进行处理

具体项目中有截取一部分行索引和截取一部分列索引的操作。

# 这里我要替换列名'2017-03-31'为'2017/03/31'格式。有两种方法一是Dataframe重建表格二是用rename替换行索引或者列索引
print(tt.shape)  # 看表格有多少行多少列
a_list=list(tt.columns)
for_col=[ x.replace('-','/') for x in a_list]

# 按照情况只选择前20列
tt.columns=for_col
tt=tt.ix[:,0:20]

# 替换行索引
b_list=list(tt.index)
for_index=['20181213{0:0>4}'.format(x) for x in b_list]   #使用列表推导和format函数改变索引
tt.index=for_index




查看重复值

然后对表格的数据进行校验。看是否存在重复值:

tt.drop_duplicates(keep=False,inplace=True)
# 重复的是科目\时间  2017-09-30  2017-06-30  2017-03-31  2016-12-31 把重复的值全部删除
print(tt[tt.duplicated(keep=False)])
# 检验。现在没有重复值

寻找异常值

      异常值分为两种:一种是非法数据,比如本来应该是数字列的中间夹杂着一些汉字或者是符号;第二种是异常数据,异乎寻常的大数值或者是小数值。

      我故意在两个数字列的空值中插入两个非法值,一个是“E”一个是“-”。然后通过程序找出异常值并修改成0

def turning(x):
    if type(x)==str:
        if x[-2:]=='亿元' or x[-2:]=='亿股':
            x=float(x[:-2])*100000000
        elif x[-2:]=='万元':
            x=float(x[:-2])*10000
        elif x[-1:]=='元':
            x=float(x[:-1])
    return x
tt=tt.applymap(turning)

# 数字列中有无字符。可以看到表格从第一列开始才有数字。判断某一列数据是否全部是int或者float。如不是打印出来
for i in range(1,len(tt.columns)):
    if ~tt.ix[:,i].apply(lambda x:isinstance(x,(int,float))).all():
        print(tt[~tt.ix[:,i].apply(lambda x:isinstance(x,(int,float)))])
        print(i)

# 找到两个非法值。需要及时处理
tt.ix['201812130091':'201812130096',:]=tt.ix['201812130091':'201812130096',:].replace('E',0).replace('-',0)
print (tt.ix['201812130091':'201812130096',:])

去除空格

注意只有对字符串类别的列才可以进行去除空格的操作。

tt.ix[:,0]=tt.ix[:,0].str.strip()

最后清洗的结果如下:













相关阅读:

Renaming columns in pandas

Delete column from pandas DataFrame using del df.column_name

在Python pandas中向现有DataFrame添加新列

How do I get the row count of a Pandas dataframe?

Select rows from a DataFrame based on values in a column in pandas

从pandas DataFrame列标题中获取列表

Selecting multiple columns in a pandas dataframe

如何迭代Pandas中的DataFrame中的行?

更改Pandas中列的数据类型

add one row in a pandas.DataFrame