数组是数据分析的基础,使用数组需要先加载两个包 Numpy 和 Pandas包
一、一维数组数据分析
在一维数组中更实用的的是pandas的Serise数组功能,numpy主要应用于值计算,两种数组都具有查询功能,向量化运算。numpy数组中每个元素都必须是同一种数据类型,列表可以是不同都数据类型。Series有索引功能,方便通过索引访问里面都元素,可以查询数组里面的描述统计信息,根据iloc属性通过位置获取值,loc属性用于根据索引获取值。s3.dropna()可删除缺失值,s3=s1.add(s2,fill_value=0)【s3=s2.add(s1,fill_value=0)】用指定值填充缺失值。
#一维数据分析
#导入包。numpy和pandas包
import numpy as np
import pandas as pd
#定义一维数组 array
a = np.array([1,2,3,4,5,6,7])
#查询
a[5]
6
#切片访问:获取指定序号范围的元素
#a[1:5]获取到的是序号从1到5的元素
a[1:5]
array([2, 3, 4, 5])
#查看数据类型dtype
a.dtype
dtype('int64')
#统计计算 平均值
a.mean()
4.0
#计算 标准差
a.std()
2.0
#向量化运算 乘以标量
b=np.array([1,2,3,4,5,6,7])
c=b*6
c
array([ 6, 12, 18, 24, 30, 36, 42])
# pandas 一维数据分析
#series一维数组结构
#定义:Pandas一维数据结构:Series
#存放6家公司某一天的股价
stockS=pd.Series([54.74,190.9,173.14,1050.3,181.86,1139.49],
index=['腾讯',
'阿里巴巴',
'苹果',
'谷歌',
'Facebook',
'亚马逊'])
print(stockS)
腾讯 54.74
阿里巴巴 190.90
苹果 173.14
谷歌 1050.30
Facebook 181.86
亚马逊 1139.49
dtype: float64
#获取描述统计信息
stockS.describe()
count 6.000000
mean 465.071667
std 491.183757
min 54.740000
25% 175.320000
50% 186.380000
75% 835.450000
max 1139.490000
dtype: float64
#iloc属性用于根据位置获取值 iloc位置
stockS.iloc[3]
1050.3
#loc属性用于根据索引获取值 根据索引index
stockS.loc['苹果']
173.14
#向量相加
s1=pd.Series([1,2,3,4,5],index=['a','b','c','d','e'])
s2=pd.Series([10,20,30,40,50],index=['a','b','c','g','h'])
s3=s1+s2
s3
a 11.0
b 22.0
c 33.0
d NaN
e NaN
g NaN
h NaN
dtype: float64
#方法1:删除空值
s3.dropna()
a 11.0
b 22.0
c 33.0
dtype: float64
# 方法2:将确实值进行填充
s3=s1.add(s2,fill_value=0)
s3
a 11.0
b 22.0
c 33.0
d 4.0
e 5.0
g 40.0
h 50.0
dtype: float64
二、二维数组数据分析
numpy二维数组array 查询元素,都是用位置来查询元素[1,2],也可以进行切片访问如[1,:]查询第二行,[:,1]查询第二列,在获取描述统计信息都时候可以通过指定数轴来查询行或者列的描述统计信息(axis=1行 axis=0列)。
pandas二维数组,数据框DataFrame 数据框每一列可以是不同类型,可以指定索引功能,每一行和每一列都有索引值。字典是无序数据结构,所以传入数据框以后是无序,需要应用有序字典对排序,使传入数据和数据框一致。获取描述统计信息获取对是列对描述统计信息。查询数据类型和series一样,有iloc和loc两种属性获取或者查询行列数据,实际应用中loc属性获取列数据更实用。条件判断:建立查询条件,返回一维数组结构(布尔值数据),应用查询条件。查询描述统计信息:读取Excel数据,打印前五行head(),查询数据类型dytpe,多少行,多少列shape,描述统计信息describe()
# ---------------这里是二维数组分割线---------------------------
#学习二维数据结构。Array和DataFrame两种方法
#
#定义二维数组
a=np.array([[1,2,3,4],
[5,6,7,8],
[9,10,11,12]
])
a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
#获取行号是1,列号是3的元素
a[1,3]
8
#获取第2列的数据
a[:,1]
array([ 2, 6, 10])
#获取第3行的数据
a[2,:]
array([ 9, 10, 11, 12])
#------Numpy数轴参数:axis-用来指定行
#如果没有指定数轴参数,会计算整个数组的平均值
a.mean()
6.5
#按轴计算:axis=1计算每一行
a.mean(axis=1)
array([ 2.5, 6.5, 10.5])
#按轴计算:axis=0计算每一列----------
a.mean(axis=0)
array([5., 6., 7., 8.])
a.std()
3.452052529534663
a.std(axis=0)
array([3.26598632, 3.26598632, 3.26598632, 3.26598632])
#-----------------Pandas二维数组:数据框(DataFrame)----------------------------
#Pandas数据框(Dataframe) 行 columns 列 index-------------------
#定义数据框 导入有序字典。定义一个有序字典,传入字典,列明
salesDict={
'购药时间':['2018-01-01 星期五','2018-01-02 星期六','2018-01-06 星期三'],
'社保卡号':['001616528','001616528','0012602828'],
'商品编码':[236701,236701,236701],
'商品名称':['强力VC银翘片','清热解毒口服液','感康'],
'销售数量':[6,1,2],
'应收金额':[82.8,28,16.8],
'实收金额':[69,24.64,15]
}
from collections import OrderedDict
salesOrderDict=OrderedDict(salesDict)
salesDf=pd.DataFrame(salesOrderDict)
salesDf
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 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
#平均值:是按每列来求平均值,计算的是每一列的数据
salesDf.mean()
商品编码 236701.000000
销售数量 3.000000
应收金额 42.533333
实收金额 36.213333
dtype: float64
salesDf.std()
商品编码 0.000000
销售数量 2.645751
应收金额 35.318739
实收金额 28.800287
dtype: float64
#查询第1行第2列的元素
salesDf.iloc[2,3]
'感康'
#获取第2行,:代表所有列
salesDf.iloc[1,:]
购药时间 2018-01-02 星期六
社保卡号 001616528
商品编码 236701
商品名称 清热解毒口服液
销售数量 1
应收金额 28
实收金额 24.64
Name: 1, dtype: object
#获取第2列,:代表所有行
salesDf.iloc[:,1]
0 001616528
1 001616528
2 0012602828
Name: 社保卡号, dtype: object
##查询数据:loc属性用于根据索引获取值------
#1) 查询第1行第1列的元素
salesDf.loc[0,'商品编码']
236701
#2) 获取某一行的所有元素,获取第2行
salesDf.loc[1,:]
购药时间 2018-01-02 星期六
社保卡号 001616528
商品编码 236701
商品名称 清热解毒口服液
销售数量 1
应收金额 28
实收金额 24.64
Name: 1, dtype: object
#获取某一列的信息
#简单的写法
salesDf['商品名称']
0 强力VC银翘片
1 清热解毒口服液
2 感康
Name: 商品名称, dtype: object
#获取商品名称这一列的信息
salesDf.loc[:,'商品名称']
0 强力VC银翘片
1 清热解毒口服液
2 感康
Name: 商品名称, dtype: object
#切片功能
#通过列表来选择某几列的数据
salesDf[['商品名称','实收金额']]
商品名称 实收金额 0 强力VC银翘片 69.00 1 清热解毒口服液 24.64 2 感康 15.00
#通过切片功能,获取指定范围的列
salesDf.loc[:,'社保卡号':'应收金额']
社保卡号 商品编码 商品名称 销售数量 应收金额 0 001616528 236701 强力VC银翘片 6 82.8 1 001616528 236701 清热解毒口服液 1 28.0 2 0012602828 236701 感康 2 16.8
#数据框复杂查询:条件判断----------------------
#通过条件判断筛选
#构建查询条件
querySer=salesDf.loc[:,'销售数量']>1
type(querySer)
pandas.core.series.Series
querySer
0 True
1 False
2 True
Name: 销售数量, dtype: bool
salesDf.loc[querySer,:]
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6 82.8 69.0 2 2018-01-06 星期三 0012602828 236701 感康 2 16.8 15.0
#查看数据集描述统计信息
#/Users/tony/第3关:数据分析的基本过程/朝阳医院2018年销售数据.xlsx
#读取Ecxcel数据
fileNameStr=r'/Users/tony/第3关:数据分析的基本过程/朝阳医院2018年销售数据.xlsx'
xls = pd.ExcelFile(fileNameStr)
salesDf = xls.parse('Sheet1')
salesDf.head(3)
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额 0 2018-01-01 星期五 1616528.0 236701.0 强力VC银翘片 6.0 82.8 69.00 1 2018-01-02 星期六 1616528.0 236701.0 清热解毒口服液 1.0 28.0 24.64 2 2018-01-06 星期三 12602828.0 236701.0 感康 2.0 16.8 15.00
salesDf.shape
(6578, 7)
salesDf.loc[:,'应收金额'].dtype
dtype('float64')
#查看每一列的统计数值
salesDf.describe()
社保卡号 商品编码 销售数量 应收金额 实收金额 count 6.576000e+03 6.577000e+03 6577.000000 6577.000000 6577.000000 mean 6.091254e+09 1.015869e+06 2.386194 50.473803 46.317510 std 4.889284e+09 5.131153e+05 2.375202 87.595925 80.976702 min 1.616528e+06 2.367010e+05 -10.000000 -374.000000 -374.000000 25% 1.014234e+08 8.614560e+05 1.000000 14.000000 12.320000 50% 1.001650e+10 8.615070e+05 2.000000 28.000000 26.600000 75% 1.004882e+10 8.690690e+05 2.000000 59.600000 53.000000 max 1.283612e+10 2.367012e+06 50.000000 2950.000000 2650.000000
三、数据分析(导入医药数据用python进行分析)
1、提出问题:
按照数据分析基本过程进行数据分析,一切数据分析的目标都是为了解决问题。
2、理解数据:采集数据,根据定义的问题来采集数据,
导入数据,比如读取excel到python中,
获取数据描述统计信息,从整体上了解数据
3、数据清洗:(60%时间用于数据清洗)
数据预处理,很多时候读取进来的数据不符合数据分析对标准,这个时候就需要对数据进行整容,方便进行分析。
4、构建模型:
对清洗后对数据进行分析,得出一些业务指标,或者应用机器学习来训练模型。
5、数据可视化:
将得出对分析结果以图片或图表展示更加清晰,更容易理解。
#实操用python 进行数据分析
#导入数据分析包
import pandas as pd
#提出问题:从销售数据中分析出以下业务指标: 1)月均消费次数2)月均消费金额3)客单价4)消费趋势
fileNameStr=r'/Users/tony/第3关:数据分析的基本过程/朝阳医院2018年销售数据.xlsx'
salesDf = pd.read_excel(fileNameStr,sheet_name='Sheet1',dtype=str)
salesDf.head()
#查看有多少行,多少列
salesDf.shape
(6578, 7)
#查看列的数据类型
salesDf.dtypes
购药时间 object
社保卡号 object
商品编码 object
商品名称 object
销售数量 object
应收金额 object
实收金额 object
dtype: object
#数据清洗 最重要 数据预处理 pre_correct
#选择子集
#列名重命名
#确实值处理
#数据类型的转换
#数据排序
#异常值处理
#1)选择子集 演示 ps :本案例不需要选择子集 需要全部数据
#subSalesDf=salesDf.loc[0:4,'购药时间':'销售数量']
subSalesDf=salesDf.loc[0:4,'购药时间':'销售数量']
subSalesDf
#2)列名重命名
#字典:旧列名和新列名对应关系
#inplace=True,数据框本身会改动 False是不会变
colNameDict = {'购药时间':'销售时间'}
salesDf.rename(columns = colNameDict,inplace=True)
salesDf.head()
#3)缺失值处理,销售数据和社保卡号不能有缺失值 选择删除确实值-----------
print('删除缺失值前大小',salesDf.shape)
删除缺失值前大小 (6578, 7)
#删除列(销售时间,社保卡号)中为空的行
#how='any' 在给定的任何一列中有缺失值就删除
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
#删除确实值后数据大小 行 列
print('删除缺失值前大小',salesDf.shape)
删除缺失值前大小 (6575, 7)
#4)数据类型的转换-----------------------
salesDf['销售数量'] = salesDf['销售数量'].astype('float')
salesDf['应收金额'] = salesDf['应收金额'].astype('float')
salesDf['实收金额'] = salesDf['实收金额'].astype('float')
print('转换后的数据类型:\n',salesDf.dtypes)
转换后的数据类型:
销售时间 object
社保卡号 object
商品编码 object
商品名称 object
销售数量 float64
应收金额 float64
实收金额 float64
dtype: object
#字符串转换为日期数据类型
testList='2018-06-03 星期五'.split(' ')
testList
['2018-06-03', '星期五']
testList[0]
'2018-06-03'
#定义函数 进行分割 分割销售日期 获取销售日期
#函数输入:timeColSer 销售时间这一列,是个Series数据类型
#函数输出:分割后的时间,返回的也是一个Series数据类型
def splitSaletime(timeColSer):
timeList=[]
for value in timeColSer:
#例如2018-01-01 星期五,分割后为:2018-01-01
dateStr=value.split(' ')[0]
timeList.append(dateStr)
#将列表转行为一维数据Series类型
timeSer=pd.Series(timeList)
return timeSer
#获取“销售时间”这一列
timeSer=salesDf.loc[:,'销售时间']
#对字符串进行分割,获取销售日期
dateSer=splitSaletime(timeSer)
dateSer[0:3]
0 2018-01-01
1 2018-01-02
2 2018-01-06
dtype: object
salesDf.loc[:,'销售时间']=dateSer
salesDf.head()
#字符串转化为日期格式
#errors='coerce' 如果原始数据不符合日期的格式,转换后的值为空值NaT
#format 是你原始数据中日期的格式
salesDf.loc[:,'销售时间']=pd.to_datetime(salesDf.loc[:,'销售时间'],
format='%Y-%m-%d',
errors='coerce')
salesDf.dtypes
销售时间 datetime64[ns]
社保卡号 object
商品编码 object
商品名称 object
销售数量 float64
应收金额 float64
实收金额 float64
dtype: object
#再进行一次 删除空值
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
print('删除缺失值前大小',salesDf.shape)
删除缺失值前大小 (6549, 7)
#5)排序 数据排序
print('排序前的数据集')
salesDf.head()
排序前的数据集
salesDf=salesDf.sort_values(by='销售时间',
ascending=True,
na_position='first')
print('排序后的数据集')
salesDf.head(3)
排序后的数据集
# 对行号进行重命名
#重命名行名(index):排序后的列索引值是之前的行号,需要修改成从0到N按顺序的索引值
salesDf=salesDf.reset_index(drop=True)
salesDf.head()
#6)异常值处理
#描述指标:查看出“销售数量”值不能小于0
salesDf.describe()
print('删除异常值前:',salesDf.shape)
删除异常值前: (6549, 7)
删除异常值后: (6549, 7)
#条件 销售数量大于0的数据 筛选条件
querySer=salesDf.loc[:,'销售数量']>0
salesDf=salesDf.loc[querySer,:]
print('删除异常值后:',salesDf.shape)
删除异常值后: (6506, 7)
print('删除异常值后:',salesDf.shape)
删除异常值后: (6506, 7)
#---------------构建模型--------------------
#1) 业务指标 计算月均消费次数=总销售数/月份数
#同一个人 同一天的销售记录 算为1次
#根据列名(销售时间,社区卡号),如果这两个列值同时相同,只保留1条,将重复的数据删除
kpi1_Df=salesDf.drop_duplicates(
subset=['销售时间', '社保卡号']
)
#总消费次数:有多少行
totalI=kpi1_Df.shape[0]
print('总消费次数=',totalI)
总消费次数= 5342
#月份数 排序
#第1步:按销售时间升序排序
kpi1_Df=kpi1_Df.sort_values(by='销售时间',
ascending=True)
#重命名行名(index)
kpi1_Df=kpi1_Df.reset_index(drop=True)
kpi1_Df.head()
#第2步:获取时间范围
#最小时间值
startTime=kpi1_Df.loc[0,'销售时间']
#最大时间值
endTime=kpi1_Df.loc[totalI-1,'销售时间']
#第3步:计算月份数
#天数
daysI=(endTime-startTime).days
#月份数: 运算符“//”表示取整除
#返回商的整数部分,例如9//2 输出结果是4
monthsI=daysI//30
print('月份数:',monthsI)
月份数: 6
#业务指标1:月均消费次数=总消费次数 / 月份数
kpi1_I=totalI // monthsI
print('业务指标1:月均消费次数=',kpi1_I)
业务指标1:月均消费次数= 890
#业务指标2: 月均消费金额 =总消费金额/月份数
#总消费金额
totalMoneyF=salesDf.loc[:,'实收金额'].sum()
#月均消费金额
monthMoneyF=totalMoneyF / monthsI
print('业务指标2:月均消费金额=',monthMoneyF)
业务指标2:月均消费金额= 50668.35166666666
#指标3:客单价 =总消费金额/总消费次数
pct=totalMoneyF / totalI
print('客单价:',pct)
客单价: 56.909417821040805
#指标4:消费趋势,画图:折线图
#在进行操作之前,先把数据复制到另一个数据框中,防止对之前清洗后的数据框造成影响
groupDf=salesDf
#第1步:重命名行名(index)为销售时间所在列的值
groupDf.index=groupDf['销售时间']
groupDf.head()
#第2步:分组
gb=groupDf.groupby(groupDf.index.month)
gb
#第3步:应用函数,计算每个月的消费总额
mounthDf=gb.sum()
mounthDf