python数据处理

# 读取数据(最好使用 object 类型读取)读取的时候用object读取,防止有些数据读不了:

data = pd.read_excel("朝阳医院2018年销售数据.xlsx", dtype="object")

 

# 修改为 DataFrame 格式

dataDF = pd.DataFrame(data)

 

 

# 查看数据的形状,即几行几列

dataDF.shape

# 查看索引

dataDF.index

# 查看每一列的列表头内容

dataDF.columns

# 查看每一列数据统计数目

dataDF.count()

 

# 使用 rename 函数,把"购药时间" 改为 "销售时间"

dataDF.rename(columns={"购药时间": "销售时间"}, inplace=True)


# 使用dropna函数删除缺失值

dataDF = dataDF.dropna()

# 将字符串转为浮点型数据

dataDF["销售数量"] = dataDF["销售数量"].astype("f8")

dataDF["应收金额"] = dataDF["应收金额"].astype("f8")

dataDF["实收金额"] = dataDF["实收金额"].astype("f8")

dataDF.dtypes

 

# 字符串转日期

 

# errors='coerce'如果原始数据不符合日期的格式,转换后的值为NaT

dataDF.loc[:, "销售时间"] = pd.to_datetime(dataDF.loc[:, "销售时间"], errors='coerce')

 

 

# 按销售时间进行升序排序

dataDF = dataDF.sort_values(by='销售时间', ascending=True)

# 重置索引(index)

dataDF = dataDF.reset_index(drop=True)

 

# 排除异常值后再次查看描述统计信息

dataDF.describe()

 

# 删除重复数据

kpi1_Df = dataDF.drop_duplicates(subset=['销售时间', '社保卡号'])

In [1]: import pandas as pd


In [2]: # 读取数据(最好使用 object 类型读取)
   ...: data = pd.read_excel("朝阳医院2018年销售数据.xlsx", dtype="object")


In [3]: # 修改为 DataFrame 格式
   ...: dataDF = pd.DataFrame(data)


In [4]: dataDF.head()
Out[4]: 
             购药时间           社保卡号    商品编码     商品名称 销售数量  应收金额   实收金额
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


In [5]: # 查看数据的形状,即几行几列
   ...: dataDF.shape
Out[5]: (6578, 7)


In [6]: # 查看索引
   ...: dataDF.index
Out[6]: RangeIndex(start=0, stop=6578, step=1)


In [7]: # 查看每一列的列表头内容
   ...: dataDF.columns
Out[7]: Index(['购药时间', '社保卡号', '商品编码', '商品名称', '销售数量', '应收金额', '实收金额'], dtype='object')


In [8]: # 查看每一列数据统计数目
   ...: dataDF.count()
Out[8]: 
购药时间    6576
社保卡号    6576
商品编码    6577
商品名称    6577
销售数量    6577
应收金额    6577
实收金额    6577
dtype: int64


In [9]: # 使用 rename 函数,把"购药时间" 改为 "销售时间"
   ...: dataDF.rename(columns={"购药时间": "销售时间"}, inplace=True)
   ...: dataDF.columns
Out[9]: Index(['销售时间', '社保卡号', '商品编码', '商品名称', '销售数量', '应收金额', '实收金额'], dtype='object')


In [10]: # 删除缺失值之前
    ...: dataDF.shape
Out[10]: (6578, 7)


In [11]: # 使用dropna函数删除缺失值
    ...: dataDF = dataDF.dropna()


In [12]: # 删除缺失值之后
    ...: dataDF.shape
Out[12]: (6575, 7)


In [13]: # 将字符串转为浮点型数据
    ...: dataDF["销售数量"] = dataDF["销售数量"].astype("f8")
    ...: dataDF["应收金额"] = dataDF["应收金额"].astype("f8")
    ...: dataDF["实收金额"] = dataDF["实收金额"].astype("f8")
    ...: dataDF.dtypes
Out[13]: 
销售时间     object
社保卡号     object
商品编码     object
商品名称     object
销售数量    float64
应收金额    float64
实收金额    float64
dtype: object


    ...: def splitsaletime(timeColser):
    ...:     timelist = []
    ...:     for t in timeColser:
    ...:         # [0]表示选取的分片,这里表示切割完后选取第一个分片
    ...:         timelist.append(t.split(" ")[0])
    ...:     # 将列表转行为一维数据Series类型
    ...:     timeser = pd.Series(timelist)
    ...:     return timeser
    ...: 


In [15]: # 定义函数将星期去除
    ...: def splitsaletime(timeColser):
    ...:     timelist = []
    ...:     for t in timeColser:
    ...:         timelist.append(t.split(" ")[0])  # [0]表示选取的分片,这里表示切割完后选取第一个分片
    ...:     timeser = pd.Series(timelist)  # 将列表转行为一维数据Series类型
    ...:     return timeser
    ...: 


In [16]: # 获取"销售时间"这一列数据
    ...: t = dataDF.loc[:, "销售时间"]
    ...: # 调用函数去除星期,获取日期
    ...: timeser = splitsaletime(t)
    ...: # 修改"销售时间"这一列日期
    ...: dataDF.loc[:, "销售时间"] = timeser
    ...: dataDF.head()
Out[16]: 
         销售时间           社保卡号    商品编码     商品名称  销售数量   应收金额    实收金额
0  2018-01-01      001616528  236701  强力VC银翘片   6.0   82.8   69.00
1  2018-01-02      001616528  236701  清热解毒口服液   1.0   28.0   24.64
2  2018-01-06     0012602828  236701       感康   2.0   16.8   15.00
3  2018-01-11  0010070343428  236701    三九感冒灵   1.0   28.0   28.00
4  2018-01-15    00101554328  236701    三九感冒灵   8.0  224.0  208.00


In [17]: # 字符串转日期
    ...: # errors='coerce'如果原始数据不符合日期的格式,转换后的值为NaT
    ...: dataDF.loc[:, "销售时间"] = pd.to_datetime(dataDF.loc[:, "销售时间"], errors='coerce')
    ...: dataDF.dtypes
Out[17]: 
销售时间    datetime64[ns]
社保卡号            object
商品编码            object
商品名称            object
销售数量           float64
应收金额           float64
实收金额           float64
dtype: object


In [18]: # 转换日期过程中不符合日期格式的数值会被转换为空值None,
    ...: # 这里删除为空的行
    ...: dataDF = dataDF.dropna()
    ...: dataDF.shape
Out[18]: (6549, 7)


In [19]: # 按销售时间进行升序排序
    ...: dataDF = dataDF.sort_values(by='销售时间', ascending=True)
    ...: dataDF.head()
Out[19]: 
           销售时间           社保卡号    商品编码          商品名称  销售数量   应收金额   实收金额
0    2018-01-01      001616528  236701       强力VC银翘片   6.0   82.8   69.0
3436 2018-01-01     0010616728  865099    硝苯地平片(心痛定)   2.0    3.4    3.0
1190 2018-01-01  0010073966328  861409  非洛地平缓释片(波依定)   5.0  162.5  145.0
3859 2018-01-01  0010073966328  866634   硝苯地平控释片(欣然)   6.0  111.0   92.5
3888 2018-01-01  0010014289328  866851   缬沙坦分散片(易达乐)   1.0   26.0   23.0


In [20]: # 重置索引(index)
    ...: dataDF = dataDF.reset_index(drop=True)
    ...: dataDF.head()
Out[20]: 
        销售时间           社保卡号    商品编码          商品名称  销售数量   应收金额   实收金额
0 2018-01-01      001616528  236701       强力VC银翘片   6.0   82.8   69.0
1 2018-01-01     0010616728  865099    硝苯地平片(心痛定)   2.0    3.4    3.0
2 2018-01-01  0010073966328  861409  非洛地平缓释片(波依定)   5.0  162.5  145.0
3 2018-01-01  0010073966328  866634   硝苯地平控释片(欣然)   6.0  111.0   92.5
4 2018-01-01  0010014289328  866851   缬沙坦分散片(易达乐)   1.0   26.0   23.0


In [21]: # 查看描述统计信息
    ...: dataDF.describe()
Out[21]: 
              销售数量         应收金额         实收金额
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


In [22]: # 将"销售数量"这一列中小于0的数排除掉
    ...: pop = dataDF.loc[:, "销售数量"] > 0
    ...: dataDF = dataDF.loc[pop, :]


In [23]: # 排除异常值后再次查看描述统计信息
    ...: dataDF.describe()
Out[23]: 
              销售数量         应收金额         实收金额
count  6506.000000  6506.000000  6506.000000
mean      2.405626    50.927897    46.727653
std       2.364565    87.650282    80.997726
min       1.000000     1.200000     0.030000
25%       1.000000    14.000000    12.600000
50%       2.000000    28.000000    27.000000
75%       2.000000    59.600000    53.000000
max      50.000000  2950.000000  2650.000000


In [24]: # 计算总消费次数
    ...: # 删除重复数据
    ...: kpi1_Df = dataDF.drop_duplicates(subset=['销售时间', '社保卡号'])


In [25]: # 删除重复数据
    ...: kpi1_Df = dataDF.drop_duplicates(subset=['销售时间', '社保卡号'])


In [26]: # 有多少行
    ...: totall = kpi1_Df.shape[0]
    ...: print('总消费次数:', totall)
总消费次数:5342


In [27]: # 按销售时间升序排序
    ...: kpi1_Df = kpi1_Df.sort_values(by='销售时间', ascending=True)


In [28]: # 重命名行名(index)
    ...: kpi1_Df = kpi1_Df.reset_index(drop=True)


In [29]: # 获取时间范围
    ...: # 最小时间值
    ...: startTime = kpi1_Df.loc[0, '销售时间']
    ...: # 最大时间值
    ...: endTime = kpi1_Df.loc[totall - 1, '销售时间']


In [30]: # 计算天数
    ...: daysI = (endTime - startTime).days


In [31]: # 月份数:运算符"//"表示取整除,返回商的整数部分
    ...: monthsI = daysI // 30
    ...: print('月份数:', monthsI)
月份数:6


In [32]: # 计算月均消费次数
    ...: kpi1_I = totall // monthsI
    ...: print('业务指标1:月均消费次数=', kpi1_I)
业务指标1:月均消费次数= 890


In [33]: # 总消费金额
    ...: totalMoneyF = dataDF.loc[:, '实收金额'].sum()


In [34]: # 月均消费金额
    ...: monthMoneyF = totalMoneyF / monthsI
    ...: print('业务指标2:月均消费金额=', monthMoneyF)
业务指标2:月均消费金额= 50668.35166666666


In [35]: # 客单价 = 总消费金额 / 总消费次数
    ...: pct = totalMoneyF / totall
    ...: print('业务指标3:客单价=', pct)
业务指标3:客单价= 56.909417821040805


In [36]: import matplotlib.pyplot as plt
    ...: 
    ...: # 画图时用于显示中文字符
    ...: from pylab import mpl
    ...: mpl.rcParams['font.sans-serif'] = ['SimHei']   # SimHei是黑体的意思


In [37]: # 在操作之前先复制一份数据,防止影响清洗后的数据
    ...: groupDf = dataDF


In [38]: # 重命名行(index)为销售时间所在列的值
    ...: groupDf.index = groupDf['销售时间']
    ...: groupDf.head()
Out[38]: 
                 销售时间           社保卡号    商品编码          商品名称  销售数量   应收金额   实收金额
销售时间
2018-01-01 2018-01-01      001616528  236701       强力VC银翘片   6.0   82.8   69.0
2018-01-01 2018-01-01     0010616728  865099    硝苯地平片(心痛定)   2.0    3.4    3.0
2018-01-01 2018-01-01  0010073966328  861409  非洛地平缓释片(波依定)   5.0  162.5  145.0
2018-01-01 2018-01-01  0010073966328  866634   硝苯地平控释片(欣然)   6.0  111.0   92.5
2018-01-01 2018-01-01  0010014289328  866851   缬沙坦分散片(易达乐)   1.0   26.0   23.0


In [39]: # 画图
    ...: plt.plot(groupDf['实收金额'])
    ...: plt.title('按天消费金额图')
    ...: plt.xlabel('时间')
    ...: plt.ylabel('实收金额')
Out[39]: <matplotlib.text.Text at 0xe16a278>


In [40]: # 保存图片
    ...: plt.savefig('./day.png')
    ...: # 显示图片
    ...: plt.show()


In [41]: # 将销售时间聚合按月分组
    ...: gb = groupDf.groupby(groupDf.index.month)
    ...: gb
Out[41]: <pandas.core.groupby.DataFrameGroupBy object at 0x000000000E184B38>


In [42]: # 应用函数,计算每个月的消费总额
    ...: monthDf = gb.sum()
    ...: monthDf
Out[42]: 
        销售数量     应收金额      实收金额
销售时间
1     2527.0  53561.6  49461.19
2     1858.0  42028.8  38790.38
3     2225.0  45318.0  41597.51
4     3005.0  54296.3  48787.84
5     2225.0  51263.4  46925.27
6     2328.0  52300.8  48327.70
7     1483.0  32568.0  30120.22


In [43]: # 描绘按月消费金额图
    ...: plt.plot(monthDf['实收金额'])
    ...: plt.title('按月消费金额图')
    ...: plt.xlabel('月份')
    ...: plt.ylabel('实收金额')
Out[43]: <matplotlib.text.Text at 0xe81d400>


In [44]: # 保存图片
    ...: plt.savefig('./month.png')
    ...: # 显示图片
    ...: plt.show()


In [45]: # 聚合统计各种药品的销售数量
    ...: medicine = groupDf[['商品名称','销售数量']]
    ...: bk = medicine.groupby('商品名称')[['销售数量']]
    ...: re_medicine = bk.sum()


In [46]: # 对药品销售数量按降序排序
    ...: re_medicine = re_medicine.sort_values(by='销售数量',ascending=False)
    ...: re_medicine.head()
Out[46]: 
                  销售数量
商品名称
苯磺酸氨氯地平片(安内真)   1781.0
开博通             1440.0
酒石酸美托洛尔片(倍他乐克)  1140.0
硝苯地平片(心痛定)       825.0
苯磺酸氨氯地平片(络活喜)    796.0


In [47]: # 截取销售数量最多的十种药品
    ...: top_medicine = re_medicine.iloc[:10,:]
    ...: top_medicine
Out[47]: 
                     销售数量
商品名称
苯磺酸氨氯地平片(安内真)      1781.0
开博通                1440.0
酒石酸美托洛尔片(倍他乐克)     1140.0
硝苯地平片(心痛定)          825.0
苯磺酸氨氯地平片(络活喜)       796.0
复方利血平片(复方降压片)       515.0
G琥珀酸美托洛尔缓释片(倍他乐克)   509.0
缬沙坦胶囊(代文)           445.0
非洛地平缓释片(波依定)        375.0
高特灵                 366.0


In [48]: # 用条形图展示销售数量前十的药品
    ...: top_medicine.plot(kind='bar')
    ...: plt.title('药品销售前十情况')
    ...: plt.xlabel('药品种类')
    ...: plt.ylabel('销售数量')
    ...: plt.legend(loc=0)
Out[48]: <matplotlib.legend.Legend at 0xe456cf8>


In [49]: # 保存图片
    ...: plt.savefig('./medicine.png')
    ...: # 显示图片
    ...: plt.show()

 

 

posted @ 2019-11-02 17:44  hehe哒  阅读(536)  评论(0编辑  收藏  举报