python数据分析&办公自动化实战(三):数据预处理/数据清洗

#简介#

本篇是数据清洗的一点经验总结,涉及到以下功能:预览、异常值处理、数据类型转换、字符串操作、选取行列、通过定义函数实现规则判断等,依然是代码+注释+总结

任务目标:将开放收入表里的各种数据进行预处理,以满足分析要求。

目标拆解:逢山开路,遇水架桥,直到数据符合可用标准。

#代码展示#

#仅展示思路,代码做了简化

import os,sys

import numpy as np

import pandas as pd

import openpyxl 

import csv

import xlwt

#遍历文件夹,输出文件夹下所有的文件路径及名称

def walk(path):

        if not os.path.exists(path):

                return -1

        for root,dirs,names in os.walk(path):

                for filename in names:

                        if os.path.splitext(filename)[1]=='.csv':

                                docs=os.path.join(root,filename)

                                print(docs)

                                csvlist.append(docs)

#定义函数实现规则判断

def  pro(a):

        if "内蒙古" in a or "山西" in a:

                return "晋蒙战区"

         elif  a  in  list1:

                  return a

          else:

                   return "其他"

csvlist=[]

cur_path=os.getcwd()

walk(cur_path)

list1=["北京战区","河北战区","山东战区","天津战区","晋蒙战区","其他"]

for    doc    in    csvlist:

            df=pd.read_csv(doc,encoding="gbk")

            df=df[df["自营外单"].isin([0])][["月份","客户名称","始发一级战区","商家渠道名称","自营外单","外单内部B商家","单量","重量","收入","成本"]]

            df.head(10)

            df.dtypes()

            df.info()

            df["商家渠道名称"]=df["商家渠道名称"].astype(str)

            df=df[~df["商家渠道名称"].str.contains("冷链|生鲜|医药")]

            df["归属战区"]=df.apply(lambdadf:pro(df.始发一级战区),axis=1)

            df[["收入","成本"]].fillna(0)

            df.groupby([["月份","始发一级战区"]]).sum().reset_index()

            df["单均收入"]=df[["收入","单量"]].apply(lambdadf:df["收入"]/df["单量"],axis=1)

            df["单公斤收入"]=df[["收入","重量"]].apply(lambdadf:df["收入"]/df["重量"],axis=1)

            columns=["月份","始发一级战区","单量","重量","收入","单均收入","单公斤收入"]

            df.to_csv("汇总数据.csv",columns=columns,encoding="gbk")

#代码拆解#

遍历文件夹、读取csv部分与上一篇相同,此处不做赘述。

数据预览

df.head(10)    #预览前10行数据

df.dtypes()    #显示每个字段的数据类型

df.info()    #显示每个字段的信息,包含位数、数据类型等

df.shape()    #显示数据文件的行列形状;另,numpy创建数组时支持reshape()改变行列结构

异常值处理

重复值去重,缺失值填充,偏离值调整

重复值去重:

df.drop_duplicates(subset=[],keep='first',inplace=False)

#subset参数为选定的列,keep参数决定保留的值,inplace决定是否替代

缺失值处理:

df[].isnull()#判断是否为缺失值,输出一列True or False布尔型

df.dropna()#去除缺失值,此时去除的是数据表中的整行,可通过调整参数实现其他功能

df.dropna(how="all",axis=1)#去除所有值为空的列,axis参数决定行列

df.fillna(0)#以0填充缺失值

关于fillna()函数的各参数,@Denver_Liao 的这篇文章写的很详细:https://blog.csdn.net/weixin_39549734/article/details/81221276

如何处理缺失值更合理的问题需要具体情况具体分析;偏离值的调整涉及到更深层次的统计学知识,限于所知不做讨论;

数据类型转换

对行列的值进行操作时,会对列的数据类型有要求。比如如果某一列有多种数据类型,pandas读取csv时会进行报错,此时就需要指定读取列的数据类型。

转换数据类型的方式主要有两种:使用库的函数转换或者通过自定义函数转换

通过astype函数和pandas自带函数

df.dtypes()#查看字段数据类型

df[].astype(str)#转换为字符串

df[].astype(float)#转换为浮点数(要求为全数字的字符串,不能包含特殊字符)

df[].astype(int)#转换为整数

pd.to_numeric(df["收入"],errors="coerce").fillna(0)#转换为数字型,无法识别字符串;errors参数可选填"coerce"(填充为空值NaN)、"ignore"(忽略,输出原值)或"raise"(报错)

pd.to_datetime(df[['Month','Day','Year']])#将年月日进行合并

通过自定义函数

定义函数法:

def  convert(a):

        b=a.replace(r'[^\w\s]+','')

        returnfloat(b)#将列a中的特殊符号去除,然后转换为float浮点数,需要string库支持

快捷方法:利用apply函数等

df["单量"]=df["单量"].str.replace(r'[^\w\s]+','').astype("int")

df["金额"].apply(lambdax:x.replace("¥","")).astype("float64")

关于数据类型转换,这篇博客写的不错:https://www.cnblogs.com/onemorepoint/p/9404753.html

本文未对时间日期类数据类型的转换进行讨论,日后有机会再补一篇

字符串操作

对字符串的拆分合并、调整替换等

val.split(',')对val按,拆分;

pieces = [x.strip() for x in val.split(',')]split和strip用于清除空格;

字符串替换见数据类型转换replace部分

选取行列

df=df[df["自营外单"].isin([0])][["月份","客户名称","收入","成本"]]

#后半段为筛选条件,选取"自营外单"字段值为0、特定列名的部分;将其赋值给df实现替换;

#bool判断条件部分暂时只能写一个,如果写两个,如df[df["自营外单"].isin([0])][df["外单内部B商家"].isin([0])]会报逻辑错误

df[].isin(["a","b"])#函数用于选择特定列值中包含a或者b的行

df=df[~df["商家渠道名称"].str.contains("冷链|生鲜|医药")]#通过str.contains()函数筛选包含关键字字符串的行,“或”以“|”符号表示;

df=df[df["自营外单"]=="0"]#以布尔值进行判断;

df.iloc[[0:5],[0:5]]#选取6×6范围内的单元格,前为行后为列,只有:表示全选

自定义函数规则判断

很简单有效的方法,展示几个例子:

list1=["北京战区","河北战区","山东战区","天津战区","晋蒙战区","其他"]

def    pro(a):

        if  "内蒙古"  in  a  or  "山西"  in a:

                return  "晋蒙战区"

        elif  a in list1:

                return a

         else:

                return "其他"

#用于规避0/0的bug:

def  div(a,b):

        if  b==0 or a==0:

                return 0

        else:

                return  a/b

自定义函数实现规则是个很有效的手段,应用起来也很简单方便,通过apply&lambda函数就可以实现;如df["归属战区"] = df.apply(lambda df:pro(df.始发一级战区),axis=1),如果参数为某一列,需要以 df.列名 设置参数

以上就是本次的分享了,零零散散扯了很多,希望能让大家少走些弯路~

CSDN同作者,博文连接https://blog.csdn.net/z1272578750/article/details/104008047

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容