Python 基于pandas的Excel数据分析(一)
写这篇文的目的在于记录一下看到并实践了的一些内容:今天分享的是基于SODA大赛公开数据集当中,一卡通数据集的简单清洗,数据的获取可以直接去SODA官网溜一圈看一下,数据内容如下:
根据数据说明:0代表一卡通卡号,1代表日期,2代表时间,3代表使用卡的地点,4代表交通方式,5代表花费,6代表卡的类型。那么有力这些信息我们要做什么呢,首先明确作业目标才能围绕目标进行清洗策越的制定,对了,得到的数据是csv格式,我人为改了一下,把数字标题替换成了,cardId,date,time,station,way,cost,discount等文字标题并存成了xls格式,其实,不这么做也不影响接下来的分析工作,因为本文要用的pandas其实已经提供了读取excel和csv的方法;
好了回到正题,我们的作业内容,其实我们知道一般正常的乘车操作流程应该是:进站->出站,那么这个过程中是有cardId相同的卡所发出的一组行为,而一组正常的消费行为应该是:进站(cost = 0)->出站(cost > 0),对同对这些行为的判读我们可以从数据中提取出某一名乘客(一卡通),从哪一站上车到哪一站下车,中途的花费,路程时间等信息。好了,有了作业目标我们应该好好分析下数据,所谓清洗重要的一点就是对脏数据的剔除,其实在众多数据中,会存在如下的扰乱信息:(1)只有进站或出站信息,缺少进站或出站信息;(2)有进出站信息但是两次消费结果均为0,或者两次消费结果均不为0;
针对上面的情况就是我们需要提出的脏数据,因为脏数据的存在会影响我们正常的数据分析行为,当然脏数据也有它的价值,比如我们可以针对脏数据进行一定分析,脏数据的出现因素,针对情况(1)的脏数据其可能出现的情况可能是因为某个乘客逃票,或者漏刷导致的,如果有许多乘客都在某一站点发生信息缺失的情况,那是不是说明该站点的机器存在问题或者是该站点附近存在什么特殊的组织.....
好了上家伙,错了,是上代码,本文主要用到pandas,xlrd,xlwt如果运行过程中报了缺少某个模块,请自行脑补上,啊不是,是自行安装上:
import pandas as pd
import xlrd
import xlwt#首先我们要读取数据:
df=pd.read_excel(excel_Path)#如果是csv就用read_csv#读取出行方式为地铁的数据
df = df[df['way'] == '地铁']
#把时间和日期字段相连,整合为datetime格式
df["date"] = df["date"].apply(lambda x:x.strftime("%Y-%m-%d"))
df["time"] = df["time"].apply(lambda x:x.strftime("%H:%M:%S"))
df["time"] = df['date']+' '+df['time']
df["time"] = pd.to_datetime(df["time"])
#根据卡号和日期进行排序
df = df.sort_values(['cardId','time'])
通过上面的代码基本可以出现一下效果了:
cardId date time station way cost discount
290 2856179 2016-03-01 2016-03-01 14:59:03 9号线打浦桥 地铁 0 非优惠
291 2856179 2016-03-01 2016-03-01 15:13:46 9号线桂林路 地铁 3 优惠
746 2903472 2016-03-01 2016-03-01 17:03:36 7号线长寿路 地铁 0 非优惠
745 2903472 2016-03-01 2016-03-01 17:20:03 10号线新天地 地铁 3 非优惠
298 100661308 2016-03-01 2016-03-01 08:01:28 1号线莘庄 地铁 0 非优惠
go on:
#添加新的列
#shift函数用于将整体的行进行移动,正数代表整体下移,挤掉最后的;负数代表整体上移,挤掉最上的
df['id_latter'] = df['cardId'].shift(-1)
df['id_former'] = df['cardId'].shift(1)
df['total_cost'] = df['cost'].shift(-1)
df['des_station'] = df['station'].shift(-1)
df['des_time'] = df['time'].shift(-1)
到此我们需要的一些准备基本就完成了,那么现在开始对脏数据进行清理:按照之前我们说的情况可以做出一下的逻辑判断:
def judge_vaild(df):
if (df['cost'] == 0) & (df['id_latter'] > 0) & (df['cardId'] == df['id_latter']):
vaild = 1
elif (df['cost'] > 0) & (df['total_cost'] == 0) & (df['cardId'] == df['id_former']):
vaild = 1
else:
vaild = -1
return vaild
数据是一条一条进行逻辑筛选,且已经经过了上门的排序。逻辑上就是判断如果当前的cost等于0那么理论上你应该是进站点,对应的下一站cost应该大于0,那么该条记录应该为有效的数据,如果当前cost大于0,理论上应该为出站点,那么该条记录的上一条记录在cost上应该为0。
然后删除掉脏数据:
df.drop(index=(df.loc[(df['vaild'] ==-1)].index),inplace=True)
其实至此,数据的清洗就基本完成了,我可以简单的打印以及输出excel:
df['cost_time'] = df.apply(lambda x: x['des_time']-x['time'],axis=1)
df.drop(index=(df.loc[(df['cost']!=0)].index),inplace=True)
df.to_excel(out_path)
df = df[['cardId','station','des_station','total_cost','cost_time','way','discount']]
结果如下:
cardId station des_station total_cost cost_time way discount
290 2856179 9号线打浦桥 9号线桂林路 3.0 00:14:43 地铁 非优惠
746 2903472 7号线长寿路 10号线新天地 3.0 00:16:27 地铁 非优惠
298 100661308 1号线莘庄 1号线黄陂南路 4.0 00:51:36 地铁 非优惠
296 100661308 1号线黄陂南路 1号线莘庄 4.0 00:33:13 地铁 非优惠
其实数据分析结果应该用可视化的图表之类的进行展示,奈何,暂且还没get到这项技能,今天的分享也只是看了别人的对象亲手实践了一下。关于本文的具体一些内容及可视化结果可以去 微信公众号搜索:Yuan的数据分析,当然该公众号与博主无关,但是是本文的参考对象,本文实践内容及参考代码均来自于其分享的某篇文章。