前言:本文介绍了Python的一维数组分析和二维数组分析的相关基础知识点,以及简单地介绍了一个销售案例的数据分析。
1、一维数组分析
#导入numpy包
import numpy as np
#导入pandas包
import pandas as pd
- Numpy一维数组
#定义:一维数组array
a=np.array([2,3,4,5])
#1)查询元素
a[0]
2
#2)切片访问
a[1:3]
array([3, 4])
#3)循环访问
for i in a:
print(i)
2
3
4
5
#4)数据类型
#dtype详细信息参考网址:https://docs.scipy.org/doc/numpy-1.10.1/reference/arrays.dtypes.html
a.dtype
dtype('int32')
- Numpy一维数组与列表的区别
#一维数组的值只能为同种类型的数据
#1、统计功能:平均值mean()和标准差std()
a.mean()
3.5
a.std()
1.118033988749895
#2.向量化计算
#1)向量相加
a+a
array([ 4, 6, 8, 10])
#2)乘以标量
a*4
array([ 8, 12, 16, 20])
#3)乘以向量
a*a
array([ 4, 9, 16, 25])
- Pandas一维数据结构
stockS=pd.Series([54,190.9,173.14,1050.3,181.86,1139.49],
index=['腾讯','阿里巴巴','苹果','谷歌','Facebook','亚马逊'])
#描述统计信息
stockS
腾讯 54.00
阿里巴巴 190.90
苹果 173.14
谷歌 1050.30
Facebook 181.86
亚马逊 1139.49
dtype: float64
stockS.describe()
count 6.000000
mean 464.948333
std 491.307473
min 54.000000
25% 175.320000
50% 186.380000
75% 835.450000
max 1139.490000
dtype: float64
#iloc属性用于根据位置获取值
stockS.iloc[0]
54.0
#loc属性根据索引获取值
stockS.loc['腾讯']
54.0
- 向量相加
#向量化运算:向量相加
s1=pd.Series([1,2,3,4],index=['a','b','c','d'])
s2=pd.Series([5,6,7,8],index=['a','b','e','f'])
s3=s1+s2
s3
a 6.0
b 8.0
c NaN
d NaN
e NaN
f NaN
dtype: float64
#方法1:删除缺失值
s3.dropna()
a 6.0
b 8.0
dtype: float64
#方法2:将缺失值填充
s3=s1.add(s2,fill_value=1)#fill_value代表填充值为1
s3
a 6.0
b 8.0
c 4.0
d 5.0
e 8.0
f 9.0
dtype: float64
2、二维数据分析
- Numpy二维数据结构
#定义二维数组
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)查询元素
a[0,2]
3
#2)获取第一行
a[0,:]
array([1, 2, 3, 4])
#3)获取第一列
a[:,0]
array([1, 5, 9])
- Numpy数轴参数
#按所有行所有列来计算
a.mean()
6.5
#按轴计算,axis=1计算每一行,axis=0计算每一列
a.mean(axis=1)
array([ 2.5, 6.5, 10.5])
a.mean(axis=0)
array([5., 6., 7., 8.])
- Pandas数据框(DataFrame)
Pandas二维数组相对于Numpy有两个优点:
1、Pandas数据框中每一列可以是不同的类型,方便表示Excel里的数据。
2、有类似Pandas一维数组里Series索引的功能,每行每列都有其索引值,有利于存储表格数据。#Numpy二维数组array没有iloc和loc功能
#第一步:定义一个字典,映射列名与对应列的值
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]
}
#第二步:定义数据框,参数传入字典
salesDf=pd.DataFrame(salesDict)
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
#1.有序的数据框
#第一步:定义一个字典,映射列名与对应列的值
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(salesDf)
#第四步:定义数据框:传入字典,列名
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
#2.平均值计算
#是按每列来求平均值
salesDf.mean()#相当于salesDf.mean(axis=0)
商品编码 236701.000000
销售数量 3.000000
应收金额 42.533333
实收金额 36.213333
dtype: float64
salesDf.mean(axis=1)#是按每行来求平均值
0 59214.70
1 59188.66
2 59183.70
dtype: float64
- iloc属性用于根据位置获取值
#1)查询元素
salesDf.iloc[0,1]
'001616528'
#2)获取第一行
salesDf.iloc[0,:]
购药时间 2018-01-01 星期五
社保卡号 001616528
商品编码 236701
商品名称 强力VC银翘片
销售数量 6
应收金额 82.8
实收金额 69
Name: 0, dtype: object
#3)获取第一列
salesDf.iloc[:,0]
0 2018-01-01 星期五
1 2018-01-02 星期六
2 2018-01-06 星期三
Name: 购药时间, dtype: object
- loc属性根据索引获取值
#1)查询元素
salesDf.loc[0,'商品编码']
236701
#2)获取第一行
salesDf.loc[0,:]
购药时间 2018-01-01 星期五
社保卡号 001616528
商品编码 236701
商品名称 强力VC银翘片
销售数量 6
应收金额 82.8
实收金额 69
Name: 0, dtype: object
#3)获取第一列
salesDf.loc[:,'商品名称']
0 强力VC银翘片
1 清热解毒口服液
2 感康
Name: 商品名称, dtype: object
#4)列表功能:以插入列表的形式查询某几列:
salesDf[['商品名称','销售数量','实收金额']]
商品名称 销售数量 实收金额
0 强力VC银翘片 6 69.00
1 清热解毒口服液 1 24.64
2 感康 2 15.00
#5)切片功能:以切片的形式指定某两列之间的范围
salesDf.loc[:,'商品名称':'实收金额']
商品名称 销售数量 应收金额 实收金额
0 强力VC银翘片 6 82.8 69.00
1 清热解毒口服液 1 28.0 24.64
2 感康 2 16.8 15.00
- 通过条件判断筛选
#1)构建查询条件
querySer=salesDf.loc[:,'销售数量']>1
type(querySer)
pandas.core.series.Series
querySer#得到的是pandas的一维数组(Series),值是布尔类型
0 True
1 False
2 True
Name: 销售数量, dtype: bool
#2)应用查询条件
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
数据集描述统计信息
#1)读取Excel数据
fileNameStr='E:\我要成为一名数据分析师\猴子聊人物\跟猴子学习人工智能核心技术\数据分析(中级)(Python)\第3关:数据分析的基本过程\朝阳医院2018年销售数据.xlsx'
xls=pd.ExcelFile(fileNameStr)
salesDf=xls.parse('Sheet1')#parse代表读取
#2)打印前5行
salesDf.head()#head()只取前5行,tail()是取后5行
购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
6573 2018-04-27 星期三 1.078861e+08 2367011.0 高特灵 10.0 56.0 54.80
6574 NaN NaN NaN NaN NaN NaN NaN
6575 2018-04-27 星期三 1.008787e+10 2367011.0 高特灵 2.0 11.2 9.86
6576 2018-04-27 星期三 1.340663e+07 2367011.0 高特灵 1.0 5.6 5.00
6577 2018-04-28 星期四 1.192693e+07 2367011.0 高特灵 2.0 11.2 10.00
#3)查看列的数据类型:dtype
salesDf.loc[:,'销售数量'].dtype
dtype('float64')
#4)有多少行,多少列 shape
#有多少行 shape[0]
#多少列 shape[1]
print(salesDf.shape)
print(salesDf.shape[0])
print(salesDf.shape[1])
(6578, 7)
6578
7
#5)每一列的统计数
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
3、案例销售数据
数据分析的基本过程:
1、提出问题(明确实际问题)
2、理解数据(采集数据,导入数据,查看分析数据的整体信息,字段信息)
3、数据清洗
4、构建模型(简单的分析得出一些业务指标,复杂的分析运用机器学习的算法训练模型)
5、数据可视化
1)、提出问题
业务指标一:月均消费次数
业务指标二:月均消费金额
业务指标三:客单价
业务指标四:消费趋势
2)、理解数据
#1)读取Excel数据
#读取Excel数据,统一先按照object(字符串str)读入,保证数据读取正确,之后转换
fileNameStr='E:\我要成为一名数据分析师\猴子聊人物\跟猴子学习人工智能核心技术\数据分析(中级)(Python)\第3关:数据分析的基本过程\朝阳医院2018年销售数据.xlsx'
xls=pd.ExcelFile(fileNameStr,dtype='object')
salesDf=xls.parse('Sheet1',dtype='object')#parse代表读取
#2)打印前5行,查看数据读取是否正确
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
#3)查看数据类型
salesDf.dtypes
购药时间 object
社保卡号 object
商品编码 object
商品名称 object
销售数量 object
应收金额 object
实收金额 object
dtype: object
3)、数据清洗
数据清洗步骤: 选择子集 ——列名重命名——缺失数据处理——数据类型转换——数据排序 ——异常值处理
#1)选择子集(本案例不需要选择子集)
subsalesDf=salesDf.loc[0:4,'购药时间':'销售数量']
''' 这里与salesDf.iloc[0:4,'购药时间':'销售数量']得到的数据不同,是由于iloc与loc的获取值的方式不同造成的。 具体情况参考如下(其中还有对ix[]的介绍): https://stackoverflow.com/questions/31593201/pandas-iloc-vs-ix-vs-loc-explanation-how-are-they-different '''
subsalesDf
购药时间 社保卡号 商品编码 商品名称 销售数量
0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6
1 2018-01-02 星期六 001616528 236701 清热解毒口服液 1
2 2018-01-06 星期三 0012602828 236701 感康 2
3 2018-01-11 星期一 0010070343428 236701 三九感冒灵 1
4 2018-01-15 星期五 00101554328 236701 三九感冒灵 8
#2)列名重命名
#字典:旧列名和新列名对应关系
colNameDict={'购药时间':'销售时间'}
salesDf.rename(columns=colNameDict,inplace=True)
''' inplace=False,数据框本身不会变,而会创建一个新的数据框,默认的inplace为False 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
#3)缺失数据处理
print('删除缺失值前大小:',salesDf.shape)
删除缺失值前大小: (6578, 7)
#删除列(销售时间,社保卡号)中为空的行
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')#subset指定删除列的列表,how指定如何删除数据
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
#字符串分割split
testList='2018-06-03 星期五'.split(' ')
testList
['2018-06-03', '星期五']
testList[0]
'2018-06-03'
''' 定义函数:分割销售日期,获取销售日期 输入:timeSer销售时间这一列,是一个Series数据类型 输出:分割后的时间,返回也是个Series的数据类型 '''
def splitSaletimen(timeSer):
timeList=[]
for value in timeSer:
dateStr=value.split(' ')[0]
timeList.append(dateStr)
timeSer3=pd.Series(timeList)
return timeSer3
#获取销售时间这一列
timeSer2=salesDf.loc[:,'销售时间']
#对字符串进行分割,获取销售日期
timeSer4=splitSaletimen(timeSer2)
timeSer4[0:3]
0 2018-01-01
1 2018-01-02
2 2018-01-06
dtype: object
#修改销售时间这一列的值
salesDf.loc[:,'销售时间']=timeSer4
#查看前5行销售时间
salesDf.loc[:,'销售时间'].head()
0 2018-01-01
1 2018-01-02
2 2018-01-06
3 2018-01-11
4 2018-01-15
Name: 销售时间, dtype: object
#format 是你原始数据中日期的格式
#errors='coerce'代表原始数据不符合日期的格式,转换后的值为NaT
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
''' 转换日期过程中不符合日期格式的数值会被转换为空值None, 这里删除列(销售时间,社保卡号)为空的行 '''
#删除缺失值
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
salesDf.shape
(6549, 7)
#5)数据排序
''' by:按那几列排序 ascending=True 表示升序排列 ascending=False 表示降序排列 '''
salesDf=salesDf.sort_values(by='销售时间',ascending=True)
#重命名行名
salesDf=salesDf.reset_index(drop=True)
salesDf.head()
销售时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额
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
#6)异常值处理
#删除异常值:通过条件判断筛选出数据
#查询条件
querySer=salesDf.loc[:,'销售数量']>0
print('删除异常值前:',salesDf.shape)
salesDf=salesDf.loc[querySer,:]
print('删除异常值后:',salesDf.shape)
删除异常值前: (6549, 7)
删除异常值后: (6506, 7)
4)、构建模型
业务指标一:月均消费次数
#月均消费次数=总消费次数/月份数
#删除重复数据,同一天内同一卡号刷的两笔及以上算作一笔
kpi1_Df=salesDf.drop_duplicates(subset=['销售时间','社保卡号'])
total1=kpi1_Df.shape[0]
print('总消费次数:',total1)
总消费次数: 5342
#1)排序
#按销售时间升序排序
kpi1_Df=kpi1_Df.sort_values(by='销售时间',ascending='True')
#重命名行名(index)
kpi1_Df=kpi1_Df.reset_index(drop='True')
#2)获取时间范围
#最小时间值
startTime=kpi1_Df.loc[0,'销售时间']
#最大时间值
endTime=kpi1_Df.loc[total1-1,'销售时间']
#3)计算月份数
#天数
days1=(endTime-startTime).days
#月份数:运算符‘//’表示取整除
months1=days1//30
print('月份数:',months1)
月份数: 6
#月均消费次数
kpi1_1=total1//months1
print('业务指标一:月均消费次数=',kpi1_1)
业务指标一:月均消费次数= 890
业务指标二:月均消费金额
#月均消费金额=总消费金额/月份数
#总消费金额
totalMoneyF=salesDf.loc[:,'实收金额'].sum()
#月均消费金额
monthMoneyF=totalMoneyF/months1
print('业务指标二:月均消费金额=',monthMoneyF)
业务指标二:月均消费金额= 50668.35166666666
业务指标三:客单价
#客单价=总消费金额/总消费次数
print('业务指标三:客单价=',totalMoneyF/total1)
业务指标三:客单价= 56.909417821040805
最后献上一波Jupyter NoteBook快键键使用指南:
Jupyter NoteBook 快捷键使用指南 opus.konghy.cn
您的点赞是也是我前进的一份动力,希望能多多指导。
如有问题,欢迎指正。谢谢!