数据清洗—pandas

pandas是python中基于NumPy的数据分析科学包,有着很强大的功能。学习使用好pandas包,对数据分析有着很大的帮助。

首先认识了解NumPy,再联系起来学习pandas。NumPy中的关键就是数组array,包括一维和多维。相似的pandas中也有Series和DataFrame。常用的功能包括文件的读取,行列索引的更改,数据类型的转换,切片和索引的使用,缺失值异常值的处理,基本的统计方法,时间日期的处理,数据的排序等。

以下案例使用了一些pandas的常用功能。某医院小品销售数据分析。

Step1:

《数据清洗—pandas》

业务指标1:月均消费次数;业务指标2:月均消费金额;业务指标3:客单价;业务指标4:每月销售额。

Step2:

《数据清洗—pandas》
《数据清洗—pandas》

import pandas as pd

C:\Users\CEC\Desktop\第3关,pandas练习
fileNameStr=r'C:\Users\Administrator\Desktop\第3关,pandas练习/朝阳医院2018年销售数据.xlsx'
xls = pd.ExcelFile(fileNameStr, dtype='object')
salesDf = xls.parse('Sheet1',dtype='object')

#c查看数据基本信息
salesDf.head()
购药时间	社保卡号	商品编码	商品名称	销售数量	应收金额	实收金额
0	2018-01-01 星期五	001616528	236701	强力VC银翘片	6	82.8	69
1	2018-01-02 星期六	001616528	236701	清热解毒口服液	1	28	24.64
2	2018-01-06 星期三	0012602828	236701	感康	2	16.8	15
3	2018-01-11 星期一	0010070343428	236701	三九感冒灵	1	28	28
4	2018-01-15 星期五	00101554328	236701	三九感冒灵	8	224	208

salesDf.shape
(6578, 7)

salesDf.dtypes
购药时间    object
社保卡号    object
商品编码    object
商品名称    object
销售数量    object
应收金额    object
实收金额    object
dtype: object

Step3:

《数据清洗—pandas》
《数据清洗—pandas》

#列的重命名
salesDf.rename(columns = {'购药时间':'销售时间'},inplace=True)
salesDf.head()
销售时间	社保卡号	商品编码	商品名称	销售数量	应收金额	实收金额
0	2018-01-01 星期五	001616528	236701	强力VC银翘片	6	82.8	69
1	2018-01-02 星期六	001616528	236701	清热解毒口服液	1	28	24.64
2	2018-01-06 星期三	0012602828	236701	感康	2	16.8	15
3	2018-01-11 星期一	0010070343428	236701	三九感冒灵	1	28	28
4	2018-01-15 星期五	00101554328	236701	三九感冒灵	8	224	208

#删除列(销售时间,社保卡号)中为空的行
#how='any' 在给定的任何一列中有缺失值就删除
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
print('删除缺失后大小',salesDf.shape)
删除缺失后大小 (6575, 7)

#字符串转换为数值(浮点型)
salesDf['销售数量'] = salesDf['销售数量'].astype('int')
salesDf['应收金额'] = salesDf['应收金额'].astype('float')
salesDf['实收金额'] = salesDf['实收金额'].astype('float')
print('转换后的数据类型:\n',salesDf.dtypes)
​
转换后的数据类型:
 销售时间     object
社保卡号     object
商品编码     object
商品名称     object
销售数量      int32
应收金额    float64
实收金额    float64
dtype: object

time_date=salesDf['销售时间']
time_date.head()
0    2018-01-01 星期五
1    2018-01-02 星期六
2    2018-01-06 星期三
3    2018-01-11 星期一
4    2018-01-15 星期五
Name: 销售时间, dtype: object

#定义函数分割字符串
date2=[x.split(' ') for x in time_date]
date3=pd.Series([x[0] for x in date2])
date3.head()
0    2018-01-01
1    2018-01-02
2    2018-01-06
3    2018-01-11
4    2018-01-15
dtype: object

#定义函数分割字符串
''''def split_time(sale_time):
    time_list=[]
    for value in sale_time:
        date_time=value.split(" ")[0]
        time_list.append(date_time)
    sale_date=pd.Series(time_list)
    return sale_date
'''
'\'def split_time(sale_time):\n    time_list=[]\n    for value in sale_time:\n        date_time=value.split(" ")[0]\n        time_list.append(date_time)\n    sale_date=pd.Series(time_list)\n    return sale_date\n'

'''timeSer=salesDf.loc[:,'销售时间']
dateSer=split_time(timeSer)
dateSer.head()
'''
"timeSer=salesDf.loc[:,'销售时间']\ndateSer=split_time(timeSer)\ndateSer.head()\n"

#修改销售时间这一列的值
salesDf.loc[:,'销售时间']=date3
salesDf.head()
销售时间	社保卡号	商品编码	商品名称	销售数量	应收金额	实收金额
0	2018-01-01	001616528	236701	强力VC银翘片	6	82.8	69.00
1	2018-01-02	001616528	236701	清热解毒口服液	1	28.0	24.64
2	2018-01-06	0012602828	236701	感康	2	16.8	15.00
3	2018-01-11	0010070343428	236701	三九感冒灵	1	28.0	28.00
4	2018-01-15	00101554328	236701	三九感冒灵	8	224.0	208.00

#字符串转换为日期
salesDf.loc[:,'销售时间']=pd.to_datetime(salesDf.loc[:,'销售时间'],
                                    format='%Y-%m-%d', 
                                    errors='coerce')
salesDf.dtypes
销售时间    datetime64[ns]
社保卡号            object
商品编码            object
商品名称            object
销售数量             int32
应收金额           float64
实收金额           float64
dtype: object

#获取销售时间列
sale_time=salesDf.loc[:,'销售时间']
sale_time[:5]
0   2018-01-01
1   2018-01-02
2   2018-01-06
3   2018-01-11
4   2018-01-15
Name: 销售时间, dtype: datetime64[ns]

'''
转换日期过程中不符合日期格式的数值会被转换为空值,
这里删除列(销售时间,社保卡号)中为空的行
'''
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
salesDf.shape
(6549, 7)

#按销售日期进行升序排列
salesDf=salesDf.sort_values(by='销售时间',
                    ascending=True,
                    na_position='first')
print('排序后的数据集')
salesDf.head(3)
排序后的数据集
销售时间	社保卡号	商品编码	商品名称	销售数量	应收金额	实收金额
0	2018-01-01	001616528	236701	强力VC银翘片	6	82.8	69.0
3436	2018-01-01	0010616728	865099	硝苯地平片(心痛定)	2	3.4	3.0
1190	2018-01-01	0010073966328	861409	非洛地平缓释片(波依定)	5	162.5	145.0

#重命名行名(index):排序后的列索引值是之前的行号,需要修改成从0到N按顺序的索引值
salesDf=salesDf.reset_index(drop=True)# drop=True 删除原索引
salesDf.head()
销售时间	社保卡号	商品编码	商品名称	销售数量	应收金额	实收金额
0	2018-01-01	001616528	236701	强力VC银翘片	6	82.8	69.0
1	2018-01-01	0010616728	865099	硝苯地平片(心痛定)	2	3.4	3.0
2	2018-01-01	0010073966328	861409	非洛地平缓释片(波依定)	5	162.5	145.0
3	2018-01-01	0010073966328	866634	硝苯地平控释片(欣然)	6	111.0	92.5
4	2018-01-01	0010014289328	866851	缬沙坦分散片(易达乐)	1	26.0	23.0

#描述指标:查看出“销售数量”值不能小于0
salesDf.describe()
销售数量	应收金额	实收金额
count	6549.000000	6549.000000	6549.000000
mean	2.384486	50.449076	46.284370
std	2.375227	87.696401	81.058426
min	-10.000000	-374.000000	-374.000000
25%	1.000000	14.000000	12.320000
50%	2.000000	28.000000	26.500000
75%	2.000000	59.600000	53.000000
max	50.000000	2950.000000	2650.000000

#删除异常值:通过条件判断筛选出数据
#查询条件
querySer=salesDf.loc[:,'销售数量']>0
#应用查询条件
print('删除异常值前:',salesDf.shape)
salesDf=salesDf.loc[querySer,:]
print('删除异常值后:',salesDf.shape)
删除异常值前: (6549, 7)
删除异常值后: (6506, 7)

#删除重复数据
kpil_Df=salesDf.drop_duplicates(subset=['销售时间','社保卡号'])
total=kpil_Df.shape[0]
print("总消费次数:",total)
总消费次数: 5342

#按销售时间升序排序
kpil_Df=kpil_Df.sort_values(by='销售时间',ascending=True)
#重命名行名
kpil_Df=kpil_Df.reset_index(drop=True)

#最早时间
start_time=kpil_Df.loc[0,'销售时间']
#最晚时间
end_time=kpil_Df.loc[total-1,'销售时间']

#计算月份数
#天数
days=(end_time-start_time).days
days
months=days//30
print('月份数:',months)
月份数: 6

Step4:

《数据清洗—pandas》
《数据清洗—pandas》

4#业务指标1:月均消费次数
kpi_1=total//months
print('业务指标1:月均消费次数=',kpi_1)
#业务指标1:月均消费次数
kpi_1=total//months
print('业务指标1:月均消费次数=',kpi_1)
业务指标1:月均消费次数= 890

#业务指标2:月均消费金额
#总消费金额
total_money=salesDf['实收金额'].sum()
#月均消费金额
month_money=total_money/months
print('业务指标2:月均消费金额%s'%month_money)
业务指标2:月均消费金额50668.35166666666

#业务指标3: 客单价
pct=total_money/total
print('业务指标3,客单价:%s'%pct)
业务指标3,客单价:56.909417821040805

salesDf.loc[:,'实收金额'].plot()
<matplotlib.axes._subplots.AxesSubplot at 0x8cb0e80>

业务指标4:每月销售额
#增加销售月份列
date4=[x.split('-') for x in date3]
date5=pd.Series([x[0]+x[1] for x in date4])
date5.head()
salesDf['销售月份']=date5
salesDf.head()
销售时间	社保卡号	商品编码	商品名称	销售数量	应收金额	实收金额	销售月份
0	2018-01-01	001616528	236701	强力VC银翘片	6	82.8	69.0	201801
1	2018-01-01	0010616728	865099	硝苯地平片(心痛定)	2	3.4	3.0	201801
2	2018-01-01	0010073966328	861409	非洛地平缓释片(波依定)	5	162.5	145.0	201801
3	2018-01-01	0010073966328	866634	硝苯地平控释片(欣然)	6	111.0	92.5	201801
4	2018-01-01	0010014289328	866851	缬沙坦分散片(易达乐)	1	26.0	23.0	201801

month_sales=salesDf.groupby([salesDf['销售月份']]).sum()
month_sales
	销售数量  应收金额     实收金额
销售月份			
201801	2471	53879.1 	49005.71
201802	1819	37196.7 	34311.17
201803	2511	53360.3	        48771.80
201804	2969	61946.2 	56744.33
201805	2233	47514.5 	43916.80
201806	2167	44931.3 	41319.70
201807	1481	32508.8	        29940.60

sales_pivot=pd.pivot_table(salesDf,index='销售月份',values=['销售数量','实收金额'],aggfunc=sum,margins=True)
sales_pivot
       实收金额	     销售数量
销售月份		
201801	49005.71	2471
201802	34311.17	1819
201803	48771.80	2511
201804	56744.33	2969
201805	43916.80	2233
201806	41319.70	2167
201807	29940.60	1481
All	304010.11	15651

Step5:

《数据清洗—pandas》
《数据清洗—pandas》

这里我使用了pandas内置的可视化函数,方法与matplotlib类似。

barh1=month_sales['销售数量'].plot(kind='barh',figsize=(6,6))
barh1.legend(["sale_quantity"])

bar2=month_sales[['应收金额','实收金额']].plot(kind='bar',figsize=(6,6))
bar2.legend(["Receivable amount","Paid amount"])

《数据清洗—pandas》
每月销售量

《数据清洗—pandas》
每月应收金额和实收金额

    原文作者:张楠
    原文地址: https://zhuanlan.zhihu.com/p/46146739
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞