![1f9c3e7f3604b4bca1fc8bffacea3e7a.png](https://i-blog.csdnimg.cn/blog_migrate/9b5fc2f1594253772a1731b3af1af8f1.jpeg)
数据分析步骤 提出问题 理解数据 清洗数据 构建模型 数据可视化
1. 提出问题
- 月均消费次数
- 月均消费金额
- 客单价
- 消费趋势
2. 理解数据
- 读取excel数据
path='C:UserszhuoguanqunDesktoppython学习资料第3关:数据分析的基本过程朝阳医院2018年销售数据.xlsx'
excel=pd.ExcelFile(path,dtype='object')
salesdf=excel.parse('Sheet1',dtype='object')
2. 打印前11 行:salesdf.head(11)
![96b300c34d1faa55bcfc15fa3ba2d33b.png](https://i-blog.csdnimg.cn/blog_migrate/a8636f9cb24a487792671829f0534b66.jpeg)
有多少行,多少列:saledf.shape
(6578, 7)
查看列的数据类型:salesdf.dtypes
![c8f4dc93c313f27e813552379c983381.png](https://i-blog.csdnimg.cn/blog_migrate/b55a68310e1fea764ed21bdbe618f687.png)
3. 清洗数据
- 选择子集
#本案例不需要选择子集
salesdf.loc[0:11,'购药时间':'实收金额']
![1d33a28cc1f94f0874d217504fa01ba1.png](https://i-blog.csdnimg.cn/blog_migrate/763cee1433a8781dfdbfc49c17574f94.jpeg)
2. 列重命名
#inplace=False,数据框本身不会变,而是创建一个改动后的新的数据框,inplace默认是False,
#inplace=Ture,数据框本身会改动。
colname={'购药时间':'销售时间'}
salesdf.rename(columns=colname,inplace=True)
salesdf
![e85b0f24d8604ce25329a6f53ff4ba57.png](https://i-blog.csdnimg.cn/blog_migrate/bea0734660349fe4055adf61f0321b8f.jpeg)
3. 缺失值处理
print('删除前',salesdf.shape)
salesdf=salesdf.dropna(subset=['销售时间','社保卡号'],how='any')
print('删除后',salesdf.shape)
![a7457ca5f583edd82ca1728d3c52b23b.png](https://i-blog.csdnimg.cn/blog_migrate/64e0790c246b40eda9561a65db84b2f2.png)
4. 数据类型转换
- 字符串转换为数值(浮点数)
salesdf[['销售数量']]=salesdf[['销售数量']].astype('float')
salesdf[['应收金额']]=salesdf[['应收金额']].astype('float')
salesdf[['实收金额']]=salesdf[['实收金额']].astype('float')
salesdf.dtypes
![2a2a5641c37572addc0e3ff629d329c8.png](https://i-blog.csdnimg.cn/blog_migrate/60a9e44ac70f70f1cf10ea4a0245f0f2.png)
- 处理日期
#字符串用split分割后为List
def sptime(time):
timelist=[]
for i in time:
time1=i.split(' ')[0]
timelist.append(time1)
timeser=pd.Series(timelist)
return timeser
salesdf['销售时间']=sptime(salesdf['销售时间'])
salesdf.head()
![6f5a66d5b00dfb618fe6039a56aba279.png](https://i-blog.csdnimg.cn/blog_migrate/ca5ee8fcdd3d086c574996b34037ef5b.png)
将日期的字符串格式改为日期格式
# format是原始数据中的格式,error='coerce'如果数据格式不符合,转换后为NaT
salesdf['销售时间']=pd.to_datetime(salesdf['销售时间'],format='%Y-%m-%d',errors='coerce')
salesdf.dtypes
![9822f29710103381c7f370a08c0a3278.png](https://i-blog.csdnimg.cn/blog_migrate/cfff20ac0fdf6cf01b8107038d62017a.png)
修改为日期格式后有可能会出现缺失值
print('删除前',salesdf.shape)
salesdf=salesdf.dropna(subset=['销售时间'],how='any')
print('删除后',salesdf.shape)
![de7f6a0506d4abd1a0dd1d7bb656df6e.png](https://i-blog.csdnimg.cn/blog_migrate/ff79245b4a91ed0b7b7188193800b637.png)
5. 数据排序
#排序,ascending为True是为升序,为False时为降序,by按哪几列排序,str或list
salesdf=salesdf.sort_values(by='销售时间',ascending='True')
salesdf.head()
![afec96513469a3194253d15c2ff44835.png](https://i-blog.csdnimg.cn/blog_migrate/db91cf944c4d18f27f624d3447b76627.png)
重命名行号(index)
#drop=True: 把原来的索引index列去掉,丢掉。
#drop=False:保留原来的索引(以前的可能是乱的)
salesdf.reset_index(drop=True)
salesdf.head()
![74cfbd5c4d4e3e1cc1e2ec2819e0a46e.png](https://i-blog.csdnimg.cn/blog_migrate/98a1667343c101ecc01b8a93fe99ad08.png)
6. 异常值处理
#每一列的描述统计信息
salesdf.describe()
![9d0de0b03fb040268739a089124a27c1.png](https://i-blog.csdnimg.cn/blog_migrate/5d2123f68417ddf70f0bdf5a016a8771.png)
通过条件筛选判断
print('删除前',salesdf.shape)
salesdf=salesdf[salesdf.loc[:,'销售数量']>0]
print('删除后',salesdf.shape)
![bcb8a62dd0ae1440e7bcdec4b4ddc063.png](https://i-blog.csdnimg.cn/blog_migrate/e0d28e0fb9f9b281b536f4ee4fcce405.png)
4. 构建模型
- 月均消费次数=总消费次数/月份数、
同一天内,同一个人发生的所有消费算作一次消费
#删除重复数据,获得总消费次数
salesdf=salesdf.drop_duplicates(subset=['销售时间','社保卡号'])
salesdf.shape
![2feb068ffb3ce7c4cb9880c79c99977e.png](https://i-blog.csdnimg.cn/blog_migrate/abfa47249093f047c51ff11df8cad03e.png)
总消费次数=5342
startdate=salesdf.loc[0,'销售时间']
enddate=salesdf.loc[endline-1,'销售时间']
days=(enddate-startdate).days
monthes=days//30
print('月份数',monthes)
![7ab2a0ba299cd8a89b6420cb85fa525e.png](https://i-blog.csdnimg.cn/blog_migrate/db0279f86dd4db8be6f6b0ae6dc5c89f.png)
#月均消费次数
print('月均消费次数=',total//monthes)
![e8b21536d9d6fc539a851fda79e8e309.png](https://i-blog.csdnimg.cn/blog_migrate/11a449151968011f0f6e4e58835a1272.png)
- 月均消费金额=总消费金额/月份数
money=salesdf.loc[:,'实收金额'].sum()
monthmoney=money/monthes
print('月均消费金额='+ str(monthmoney))
![c7b64e6ca80f43e5c560fba9e497819c.png](https://i-blog.csdnimg.cn/blog_migrate/6a5a5474a2b51bb8628e3ee3d327d799.png)
- 客单件=总金额/总消费次数
#客单价
print('客单价='+str(money/total))
![5eb97d1aa988a09cb979587cfdda27df.png](https://i-blog.csdnimg.cn/blog_migrate/4de7cdd3f7622482cb0ea89d9df443fc.png)
- 消费趋势
看每月的销售额
#提取月份
salesdf['月份']=salesdf['销售时间'].dt.month
salesdf.head()
![df0ade39b9b90c095504b9ef4e7c26cd.png](https://i-blog.csdnimg.cn/blog_migrate/fb065fc91b5029b97295fb608313f72f.jpeg)
#获取每月的销量、应收金额和实收金额的和
#因为七月份的不全,所以去掉该月份的数据
month=salesdf.groupby('月份').agg('sum')
month=month.reset_index(drop=False)
month=month.drop(axis=1,index=6)
month
![f7ea9922d8a9c5cd9ea88ecab77d9b10.png](https://i-blog.csdnimg.cn/blog_migrate/46d1aae4e32dce6e4e65ca5db5ee9430.png)
5. 数据可视化
5.1 消费趋势
根据每月的销售数量、应收金额和实收金额。
ax1=month.plot(x='月份',y='实收金额',marker='o',linewidth=3)
month.plot('月份','应收金额',ax=ax1,marker='o',linewidth=3)
plt.title('1-6月销售金额趋势')
plt.grid(True)
![eb44d0cc904c0de0b3d399d09e30779e.png](https://i-blog.csdnimg.cn/blog_migrate/66bcdb78e17f575f25d994030ea0d376.png)
month.plot('月份','销售数量',marker='o',linewidth=3)
plt.title('1-6月份销售数量趋势变化')
plt.grid(True)
![b94d5175e06f354ae2b1ff29e543b4a5.png](https://i-blog.csdnimg.cn/blog_migrate/a61d966f62463b0ba86641bf48018e64.png)
![6dab12113e23b05a7748a4cd51d80e06.png](https://i-blog.csdnimg.cn/blog_migrate/7cdaa3d97538d60cda155ff78044a1a9.png)
结论:二月份销售额和销售数量都很低,因为数据原因,不进一步探索。三月份销量和五月份销量基本一致,销售额差距较大。通过对比3月和5月前五实收金额可以看到只有苯磺酸氨氯地平片(络活喜)是高于5月,其他4种均低于5月。
5.2 一周中每天的实收金额和应收金额
ax1=sum.plot('销售周','实收金额',marker='o')
sum.plot('销售周','应收金额',ax=ax1,marker='o')
plt.grid(True)
# X坐标轴值显示
x=range(7)
plt.xticks(x,sum['销售周'])
plt.xlabel(' ')
plt.show()
![314d44c8c836fbe009deb175ee492900.png](https://i-blog.csdnimg.cn/blog_migrate/a698ad238d58ffaba48330e017c3467f.png)
结论:一周中周一、周三和周四销售额最低,适合调整陈列,部署送货。周五周六是销售高峰。