新闻中心

用Numpy和Pandas分析医院销售数据(用python做医学数据分析题目)

2023-08-02
浏览次数:
返回列表
目录:常用的Python库有哪些?了解Numpy和Pandas包。数据分析的基本过程。分析医院销售数据。

一 常用的Python库有哪些?

二 了解Numpy和Pandas包

Numpy和Pandas都是Python常用的数据库,具体如下:

1 Numpy

NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

NumPy提供了一个N维数组类型ndarray(别名array):NumPy中基本的数据结构,它描述了相同类型的“items”的集合,利于节省内存和提高CPU计算时间,有丰富的函数。

2 Pandas

Pandas 是python的一个数据分析包,是基于NumPy的一种工具,该工具是为解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。

Pandas对象常见的有Series和DataFram,DataFram它是一个面向列(column-oriented)的二维表结构,且含有行标和列标:

Series类似于一维数组与字典的结合,Series对象是一种带有标签数据的一堆数组(索引在左边,值在右边),标签在Pandas中有对应的数据类型Index(即一个不可变数组,其对象中可以包含重复值,且可在多个数据间共享)。

Series的创建:

创建Series时,可通过index参数指定索引,未指定时,采用默认索引,从0 开始不断递增;

通过列表 元祖创建:索引大小必须和列表大小一致;

通过NumPy和ndarray创建:必须是一维数组,且数组大小和索引大小要一致;

通过字典创建:默认索引为字典关键字,指定索引时,以索引为键获取值,没有值时,默认为NaN;

通过标量创建:重复填充标量到每个索引上。

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引),其中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构),类似于Excel表或关系型数据库中的二维表。

DataFrame的创建:

可通过值为一维ndarray, list, dict, Series的字典或列表;二维的ndarray,单个Series,列表,一维数组;其他的DataFrame等创建;

创建DataFrame时,可通过index,columns参数指定行索引和列索引,若没有指定索引,则默认为从0开始的连续数字。

通过多个Series创建DataFrame时,多个Series对象会自动对齐。若指定了index,则会丢弃所有未和index匹配的数据。若指定的index不存在,则对应的值默认为NaN.

虽然DataFrame是以二维结构保存数据的,但你仍然可以轻松地将其表示为更高维度的数据(层次化索引的表格型结构,这是pandas中许多高级数据处理功能的关键要素)。

Pandas兼具NumPy高性能的数组计算功能以及电子表格和关系型数据库(如SQL)灵活的数据处理功能。它提供了复杂精细的索引功能,以便更为便捷地完成重塑,切片和切块,聚合以及选取数据子集等操作。尤其是对于金融行业的用户,Pandas提供了大量适用于金融数据的高性能时间序列功能和工具。

Pandas这个名字本身源于Panel data(面板数据,这是计量经济学中关于多维结构化数据集的一个术语)以及Python data analysis(Python数据分析)。

3 一维数据(向量)分析

需要先安装这两个包:numpy和pandas

需要先安装这两个包:numpy和pandas #导入numpy包 import numpy as np #导入pandas包 import pandas as pd#定义:一维数组array,参数传入的是一个列表[2,3,4,5] a = np.array([2,3,4,5])#查询 a[0]2#切片访问:获取指定序号范围的元素 #a[1:3]获取到的是序号从1到3的元素,但不包括3 #a[1:3]或获取到的是序号从1到2的元素 a[1:3]array([3, 4])#查看数据类型dtype a.dtype

dtype(int64)

dtype详细信息参考网址:Data type objects (docs.scipy.org/doc/numpy-1.10.1/reference/arrays.dtypes.html#统计计算 #平均值 a.mean()3.5#标准差 a.std()1.118033988749895#向量化运行:乘以标量 b=np.array([1,2,3]) c=b*4carray([ 4, 8, 12])#定义:Pandas一维数据结构:Series #存放6家公司某一天的股价(单位是美元)。其中腾讯427.4港元兑换成美元是54.74 stockS=pd.Series([54.74,190.9,173.14,1050.3,181.86,1139.49], index=[腾讯, 阿里巴巴, 苹果, 谷歌, Facebook, 亚马逊])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属性用于根据索引获取值 stockS.iloc[0]54.74#loc属性用于根据索引获取值 stockS.loc[腾讯]54.74#向量化运算:向量相加 s1=pd.Series([1,2,3,4],index=[a,b,c,d]) s2=pd.Series([10,20,30,40],index=[a,b,e,f]) s3=s1+s2s3

a 11.0

b 22.0

c NaN

d NaN

e NaN

f NaN

dtype: float64#方法1:删除缺失值 s3.dropna()

a 11.0

b 22.0

dtype: float64#方法2:将缺失值进行填充 s3=s1.add(s2,fill_value=0)s3

a 11.0

b 22.0

c 3.0

d 4.0

e 30.0

f 40.0

dtype: float64

4 二维数据(矩阵)分析

#导入包 import numpy as np import pandas as pdNumpy二维数据结构:Array #定义二维数组 a=np.array([ [1,2,3,4], [5,6,7,8], [9,10,11,12] ])#获取行号是0,列号是2的元素 a[0,2]3#获取第1行 a[:,0]array([1, 5, 9])#获取第1列 a[0,:]array([1, 2, 3, 4])Numpy数轴参数:axis#如果没有指定数轴参数,会计算整个数组的平均值 a.mean()#按轴计算:axis=1计算每一行 a.mean(axis=1)array([ 2.5, 6.5, 10.5])

定义数据框

Pandas二维数组:数据框(DataFrame) #第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(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()

社保卡号 5.388427e+24

商品编码 2.367010e+05

销售数量 3.000000e+00

应收金额 4.253333e+01

实收金额 3.621333e+01

dtype: float64

查询数据:iloc属性用于根据位置获取值

iloc属性用于根据位置获取值 #查询第1行第2列的元素 salesDf.iloc[0,1]001616528#获取第1行,:代表所有列 salesDf.iloc[0,:]

购药时间 2018-01-01 星期五

社保卡号 001616528

商品编码 236701

商品名称 强力VC银翘片

销售数量 6

应收金额 82.8

实收金额 69

Name: 0, dtype: object#获取第1列,:代表所有行 salesDf.iloc[:,0]

0 2018-01-01 星期五

1 2018-01-02 星期六

2 2018-01-06 星期三

Name: 购药时间, dtype: object

查询数据:loc属性用于根据索引获取值

loc属性用于根据索引获取值 #查询第1行,获取“商品编码”的元素 salesDf.loc[0,商品编码]236701#获取第1行 salesDf.loc[0,:]

购药时间 2018-01-01 星期五

社保卡号 001616528

商品编码 236701

商品名称 强力VC银翘片

销售数量 6

应收金额 82.8

实收金额 69

Name: 0, dtype: object#获取“商品名称”这一列 salesDf.loc[:,商品名称] #简单方法:获取“商品名称”这一列

salesDf[商品名称]

0 强力VC银翘片

1 清热解毒口服液

2 感康

Name: 商品名称, dtype: object

数据框复杂查询:切片功能

#通过列表来选择某几列的数据 salesDf[[商品名称,销售数量]]

即包含某几列的数据:

此处有商品名称和销售数量两个列名,则为包含此两列的数据。

列表=[商品名称,销售数量]

商品名称 销售数量

0 强力VC银翘片 6

1 清热解毒口服液 1

2 感康 2#通过切片功能,获取指定范围的列 salesDf.loc[:,购药时间:销售数量]

冒号表示切片范围:

即从商品名称到销售数量之间的列为范围,包含首尾。

列表=[商品名称,社保卡号,商品编码,商品名称,销售数量]

购药时间 社保卡号 商品编码 商品名称 销售数量

0 2018-01-01 星期五 001616528 236701 强力VC银翘片 6

1 2018-01-02 星期六 001616528 236701 清热解毒口服液 1

2 2018-01-06 星期三 0012602828 236701 感康 2

数据框复杂查询:条件判断

#通过条件判断筛选 #第1步:构建查询条件 querySer=salesDf.loc[:,销售数量]>1#通过条件判断检查对象的类型 type(querySer)pandas.core.series.Series#第2步:进行判断,如果销售数量>1则为True,反之为False querySer

0 True

1 False

2 True

Name: 销售数量, dtype: bool#第3步:根据索引loc获取 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

查看数据集描述统计信息

#读取Ecxcel数据 fileNameStr=./朝阳医院2018年销售数据.xlsx xls = pd.ExcelFile(fileNameStr) salesDf = xls.parse(Sheet1)#打印出前3行,以确保数据运行正常 salesDf.head(3)

购药时间 社保卡号 商品编码 商品名称 销售数量 应收金额 实收金额

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#有多少行,多少列 salesDf.shape(6578, 7)#查看某一列的数据类型 salesDf.loc[:,销售数量].dtypedtype(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

DataFrame 中选取数据及数据赋值方法汇总

df.at(参数1,参数2)

#表示取索引为x,列名称为Y所对应的元素的值 df.at(x,Y)

df.iloc[参数1,参数2]

DataFrame.iloc[行索引位置,列索引位置]

iloc函数是针对Dataframe行索引和列索引位置的切片方法,搭配数字序号使用

: 代表所有行或所有列

参数2可以省略,表示取所有行;或者以“:”形式表示取所有列;

参数1不可以省略,以“:”形式表示取所有列。

参数的表达方式:

数字列表:例如[1,3,5],表示取python行(列)顺序上的第1行(列)、第3行(列)、第5行(列);

布尔值列表:例如[True,Flase, True,Flase, True,Flase],表示取为True的行(列),布尔列表长度一定要跟行(列)的长度一致;

单个数字:例如5,表示取python行(列)顺序上的第5行(列);

冒号分隔的开始行号和结束行号:例如 3:5 ,表示取python行(列)顺序上的第3行(列)至第4行(列)【不包含python顺序含义上的第5行(列)】。

例子:取相应的行,列为所有的列

df.iloc[0] 取第1行,取出后格式为Series(python的顺序是从0开始的,0表示第1,2表示第3,3表示第4,以此类推);

df.iloc[[0]] 取第1(x+1)行,取出后格式为DatFrame;

df.iloc[0:1] 取第一行=第1(x+1)行至第1(y)行,取出后格式为DatFrame;

df.iloc[0:2] 取第1(x+1)行至第2(y)行,取出后格式为DatFrame;

df.iloc[[0,2]] 取第1(x+1)行和第3(y+1)行,取出后格式为DatFrame;

df.iloc[[2,4]] 取第3(x+1)行和第5(y+1)行,取出后格式为DatFrame;

df.iloc[[0,2,3]] 取第1(x+1)行、第3(y+1)行、第4(z+1)行,取出后格式为DatFrame;

df.iloc[[0,2,3,4]] 取第1(x+1)行、第3(y+1)行、第4(z+1)行、第5(w+1)行,取出后格式为DatFrame;

df.iloc[[True,True,Flase,False,False,False]] 取为True所对应的行。

例子:取相应的行,同时取相应的列

[行选取的参数,列选取的参数]

行和列参数形式均可以在4种参数表达中选择,不互斥,也就是有16种组合取值方式。

df.iloc[0,1] 取第1行第2列的值(python的顺序,2表示3行,3表示4列);

df.iloc[[0, 1], [1, 2]] 取第1(x+1)行和第2(x+1)行,然后再取第2(z+1)列和第3(w+1)列;

df.iloc[[0, 1], [1, 3]] 取第1(x+1)行和第2(y+1)行,然后再取第2(z+1)列和第4(w+1)列;

df.iloc[[0, 3], [2, 5]] 取第1(x+1)行和第4(y+1)行,然后再取第3(z+1)列和第6(w+1)列;

df.iloc[0:1,3] 取第1行=第1行(x+1)至第3(y)行,再取第4列的值;

df.iloc[0:3,3] 取第1(x+1)行至第3(y)行,再取第4(z+1)列的值;

df.iloc[2:5,5] 取第3(x+1)行至第5(y)行,再取第6(z+1)列的值;

df.iloc[:,3] 取第4(y+1)列的值;

df.iloc[0:3,1:4] 取第1(x+1)行至第3(y)行,再取第2(z+1)列至第4(w)列的值;

df.iloc[2:5,3:6] 取第3(x+1)行至第5(y)行,再取第4(z+1)列至第6列的值;

df.iloc[[True,True,Flase,False,False,False],3:6] 取为True的行,再取第4列至第6列的值;

df.iloc[[True,True,Flase,False,False,False],[True,True,Flase,False,False,False]] 取为True的行,再取为True的列。

df.loc[参数1,参数2]

DataFrame.loc[行索引名称或条件,列索引名称]

loc函数是针对Dataframe索引名称的切片方法,搭配数字序号或列名使用

若传入的不是索引名称,那么切片操作将无法执行

: 代表所有行或所有列

参数2可以省略,表示取所有行;或者以“:”形式表示取所有列;

参数1不可以省略,以“:”形式表示取所有列。

参数的表达方式:

索引或者列名称列表:例如[1,3,5],表示取索引(列名称)为1,3,5的行(列)

布尔值列表:[True,Flase, True,Flase, True,Flase],表示取为True的行(列),但是列表长度一定要跟行(列)的长度一致。

单个索引或者列名称:5,表示索引(列名称)为5的行(列)

冒号分隔的开始索引(列名称)和结束索引(列名称):3:5 表示取索引(列名称)为3至5【包含5】的行(列),字符串就按照字符串的方式排序。

例子:取相应的行,列为所有的列

df.loc[0] 取索引为1(x+1)的行,取出后格式为series;

df.loc[[0]] 取索引为1(x+1)的行,取出后格式为DatFrame;

df.loc[[2]] 取索引为3(x+1)的行,取出后格式为DatFrame;

df.loc[a:c] 取索引为a至c的行,取出后格式为DatFrame,字符串就按照字符串的方式排序;

df.loc[[a,b]] 取索引为a,和b的行,取出后格式为DatFrame;

df.loc[[False, False, True]] 取值为True的行,(布尔列表长度必须为dataframe的长度)。

例子:取相应的行,同时取相应的列

[行选取的参数,列选取的参数]

参数有4种形式,行和列的选取参数均可以在4种形式中选择,不互斥,也就是有16种组合的取值方式。

df.loc[[False, False, True],[a,c]] 取值为True的行,再取列名称为a和c的列(布尔列表的长度必须为dataframe的长度)

df.loc[[A,C],a:c] 取值索引值为A、C的行,再取列名称为a至c的列(布尔列表的长度必须为dataframe的长度)

df.loc[A:C,a] 取值索引值A至C的行,再取列名称为a的列(布尔列表的长度必须为dataframe的长度)

另外,df.loc[]支持取多重索引的值或者定位位置。

例子:取相应的行,列为所有的列

把(第一重索引,第二重索引)当做一个索引值来看,套用上面的同样的规则;

把(第一重列名,第二重列名)当做一个列名来看,套用上面的同样的规则;

df.loc[(第一重索引,第二重索引)] 取索引为(第一重索引,第二重索引)的行,取出后格式为series;

df.loc[[(第一重索引,第二重索引)]] 取索引为(第一重索引,第二重索引)的行,取出后格式为DatFrame;

df2.loc[(a,ii):(c,ii)] 取索引(a,ii)至索引(c,ii)的行;

df2.loc[(a,ii):c] 取索引(a,ii)至索引c的行,索引c的意思为所有第一重索引为c的。dataframe与array二维数组的联系与区别:

numpy数组中的每一个元素都属于同一种数据类型,这在数值计算和科学计算中是非常有用的。但是它不利于我们表示类似于Excel中的内容,因为Excel中每一列的数据类型可能都不一样

DataFrame 也有索引的功能,这使得其很容易存储常见的表格数据,DataFrame 的每一列数据可以是不同类型,这就方便表示 Excel 中的数据内容。

更多维数组等,请参考:

小知识插入:

字符串的序号:

array到底跟原生python列表的区别:

乍看上去,NumPy数组与Python列表极其相似。它们都用来装载数据,都能够快速添加或获取元素,插入和移除元素则比较慢。

当然相比python列表,numpy数组可以直接进行算术运算:

除此之外,numpy数组还具有以下特点:

更紧凑,高维时尤为明显 向量化后运算速度比列表更快 在末尾添加元素时不如列表高效 元素类型一般比较固定

array在存储数据的时候,数据与数据的地址都是连续的,这样就给使得批量操作数组元素时速度更快。这是因为array中的所有元素的类型都是相同的,而Python列表中的元素类型是任意的,所以array在存储元素时内存可以连续,而python原生list就只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面NumPy的array不及Python原生list,但在科学计算中,NumPy的array就可以省掉很多循环语句,代码使用方面比Python原生list简单的多。

三 数据分析的基本过程。

提出问题理解数据数据清洗:选择子集 列名重命名 缺失数据处理 数据类型转换 数据排序 异常值处理构建模型数据可视化

数据可视化主要由Matplotlib包处理,本文暂无。

四 分析医院销售数据。

以Excel文件医院销售数据为例,分析整个数据过程:

需要先读取excel文件的依赖包xlrd,具体操作查看:

安装好完包xlrd后,通过使用Pandas导入数据、处理数据和构建数据模型。

如果安装完包xlrd,仍然保持,将下面python代码放到一个单元格里先运行:import pip package_name=xlrd pip.main([install, 包名]) "\n如果安装完包xlrd,仍然保持,将下面python代码放到一个单元格里先运行:\nimport pip\npackage_name=xlrd\npip.main([install, 包名])\n\n"#导入数据分析包 import pandas as pd路径中最好不要有中文,或者特殊符号啥的,不然路径会提示错误找不到。 最好将文件放到一个简单的英文路径下 #excel文件路径,路径中的./表示在当前notebook所在的文件夹路径 fileNameStr=./朝阳医院2018年销售数据.xlsx 使用pandas的read_excel函数读取Ecxcel数据 参数sheet_name:数据在Excel里的哪个sheet下面,这块就写该sheet在excel里的名称 参数dtype=str 统一先按照字符串读入,之后再转换 salesDf = pd.read_excel(fileNameStr,sheet_name=Sheet1,dtype=str)

pandas的read_excel函数官网地址:

1 提出问题

数据分析的核心和目标,必须知道要分析的是什么,为什么分析,下一步才能继续进行。在此,和业务部门沟通后,得知需要分析的指标有:

1)月均消费次数;

2)月均消费金额;

3)客单价;

4)消费趋势。

2 理解数据

查看数据的相关参数,掌握大概情况。

查看数据基本信息 #打印出前5行,以确保数据运行正常 salesDf.head()#有多少行,多少列 salesDf.shape(6578, 7)#查看每一列的数据类型 salesDf.dtypes

购药时间 object

社保卡号 object

商品编码 object

商品名称 object

销售数量 object

应收金额 object

实收金额 object

dtype: object

3 数据清洗:

1)选择子集:

只选择对数据分析有意义的字段,无意义的字段隐藏掉(建议不删,保证数据的完整性)。

#注释掉 #subSalesDf=salesDf.loc[0:4,购药时间:销售数量]

2)列名重命名

#字典:旧列名和新列名对应关系 colNameDict = {购药时间:销售时间} inplace=False,数据框本身不会变,而会创建一个改动后新的数据框,默认的inplace是False inplace=True,数据框本身会改动 salesDf.rename(columns = colNameDict,inplace=True)salesDf.head()

3)缺失数据处理

python缺失值有3种:

Python内置的None值;

在pandas中,将缺失值表示为NA,表示不可用not available;

对于数值数据,pandas使用浮点值NaN(Not a Number)表示缺失数据。

后面出来数据,如果遇到错误:说什么foloat错误,那就是有缺失值,需要处理掉

所以,缺失值有3种:None,NA,NaN。

缺失值的处理可以用dropna参数的subset做处理,移除指定列为空的数据,其how=any即在给定的任何一列有缺失值就删除。具体的用法可以参见:

print(删除缺失值前大小,salesDf.shape)删除缺失值前大小 (6578, 7)#删除列(销售时间,社保卡号)中为空的行 #how=any 在给定的任何一列中有缺失值就删除 salesDf=salesDf.dropna(subset=[销售时间,社保卡号],how=any)print(删除缺失后大小,salesDf.shape)删除缺失后大小 (6575, 7)#删除缺失值,使得索引序号不连续,这里用reset_index重置索引 salesDf=salesDf.reset_index(drop=True)

在删除前,数据是6578条,删除后,数据是6575条,说明3条数据有缺失销售时间或者社保卡号。

4)数据类型转换

字符串转换为数值(浮点型)

#字符串转换为数值(浮点型) salesDf[销售数量] = salesDf[销售数量].astype(float) salesDf[应收金额] = salesDf[应收金额].astype(float) salesDf[实收金额] = salesDf[实收金额].astype(float) print(转换后的数据类型:\n,salesDf.dtypes) 运行后,会报警告SettingWithCopyWarning 一般信息有两列,一类是Warning警告信息,一类是Error错误信息。警告的信息不用管,我们只关注错误类型的信息

转换后的数据类型:

销售时间 object

社保卡号 object

商品编码 object

商品名称 object

销售数量 float64

应收金额 float64

实收金额 float64

dtype: object

\n运行后,会报警告SettingWithCopyWarning\n一般信息有两列,一类是Warning警告信息,一类是Error错误信息。\n警告的信息不用管,我们只关注错误类型的信息\n

字符串转换为日期数据类型

#测试:字符串分割 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) 注意:如果运行后报错:AttributeError: float object has no attribute split 是因为Excel中的空的cell读入pandas中是空值(NaN),这个NaN是个浮点类型,一般当作空值处理。所以要先去除NaN在进行分隔字符串"\n注意:\n如果运行后报错:AttributeError: float object has no attribute split\n是因为Excel中的空的cell读入pandas中是空值(NaN),这个NaN是个浮点类型,一般当作空值处理。\n所以要先去除NaN在进行分隔字符串\n"

那None和NaN有什么区别呢:

None是Python的一种数据类型,NaN是浮点类型,两个都用作空值。

#None和NaN的区别 print(None的数据类型,type(None)) from numpy import NaN print(NaN的数据类型,type(NaN))

None的数据类型

NaN的数据类型 <class float>数据类型转换:字符串转换为日期 #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)

5)数据排序

官网文档:

print(排序前的数据集) salesDf.head()by:按哪几列排序 ascending=True 表示升序排列, ascending=True表示降序排列na_position=True表示排序的时候,把空值放到前列,这样可以比较清晰的看到哪些地方有空值 #按销售日期进行升序排列 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()#删除异常值:通过条件判断筛选出数据 #查询条件 querySer=salesDf.loc[:,销售数量]>0 #应用查询条件 print(删除异常值前:,salesDf.shape) salesDf=salesDf.loc[querySer,:] print(删除异常值后:,salesDf.shape)

删除异常值前: (6552, 7)

删除异常值后: (6509, 7)

4 构建模型

业务指标1:月均消费次数=总消费次数 / 月份数

第一步:计算总消费次数

总消费次数:同一天内,同一个人发生的所有消费算作一次消费 #根据列名(销售时间,社区卡号),如果这两个列值同时相同,只保留1条,将重复的数据删除 kpi1_Df=salesDf.drop_duplicates( subset=[销售时间, 社保卡号] ) #总消费次数:有多少行 totalI=kpi1_Df.shape[0] print(总消费次数=,totalI)总消费次数= 5345

第二步:计算月份数

计算月份数:时间范围 #第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:月均消费金额= 50672.494999999995

指标3:客单价=总消费金额 / 总消费次数

客单价(per customer transaction)是指商场(超市)每一个顾客平均购买商品的金额,客单价也即是平均交易金额。

由于总消费金额和总消费次数已经计算出,所以可直接得出客单价。

totalMoneyF:总消费金额 totalI:总消费次数 pct=totalMoneyF / totalI print(客单价:,pct)客单价: 56.88212722170252

指标4:消费趋势,画图:折线图

指标4的计算需要用到pandas更多高级功能以及绘图等更多高级数据分析功能,在此先省略

第一步:重置索引(index)为销售时间所在列的值

#在进行操作之前,先把数据复制到另一个数据框中,防止对之前清洗后的数据框造成影响 groupDf=salesDf #第1步:重命名行名(index)为销售时间所在列的值 groupDf.index=groupDf[销售时间] groupDf.head()

第二步:根据销售时间分组

#第2步:分组 gb=groupDf.groupby(groupDf.index.month)gb<pandas.core.groupby.generic.DataFrameGroupBy object at 0x1138b23a0>

第三步:应用函数,计算每个月的消费总额

#第3步:应用函数,计算每个月的消费总额 mounthDf=gb.sum()mounthDf

注:Numpy和Pandas的更多用法,可在下方的官网文档进行学习。

搜索