numpy和pandas是使用python进行数据分析的两个基本工具。numpy在线性代数中运用较多,而pandas则更多的用来分析表结构的数据。numpy与pandas都有一维和二维数据结构。
numpy的一维数组我们称之为array。定义方式如下:
import numpy as np
a=np.array([1,2,3,4,5])
还有几个基本的应用:
#查询元素
a[0]
#切片访问
a[1:3]
#循环访问
for i in a:
print(i)
#数据类型
a.dtype
我们可以发现List和array一维数组的样子很像,那么它们有什么区别呢?
numpy之所以适用于数据分析,就是因为它具有许多List不具有的功能:
(1)统计功能
#求平均值
a.mean()
#求标准差
a.std()
#向量相加
a=np.array([1,2,3])
b=np.array([4,5,6])
a+b
a*b
pandas的一维数据结构称之为series。定义方式如下:
import pandas as pd
stocks=pd.Series([54.74,190.9,173.14,1050.3,181.86,1139.49],
index=['腾讯','阿里巴巴','苹果','谷歌','Facebook','亚马逊'])
如果说array一维数组和List比较类似,那Series就和Dictionary相像,每个索引值对应一个值。Series就是array一维数组的升级版,具有许多它不具有的功能:
#获取描述统计信息
stocks.describe()
#运用iloc属性根据位置获取值
stocks.iloc[1]
#运用loc属性根据索引值获取值
stocks.loc['腾讯']
#根据索引值进行向量的加减乘除,若索引值不对应,则会产生数值型缺失值NaN
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+s2
s3
#那出现缺失值了,如何删除呢
s3.dropna()
s3
下面我们来看二位数据结构,既有行也有列。
Numy中利用array来创建二维数组,而Pandas利用DataFrame来创建二维数组。
先来看array二维数组的几个简单操作:
#定义二维数组(创建一个三行四列二维数组)
a=np.array([
[1,2,3,4],
[5,6,7,8],
9,10,11,12]
])
#查询元素 前面代表行号,后面代表列号
a[0,2]
#获取第一行
a[0,:]
#获取第一列
a[:,0]
#计算平均值、标准差的办法(array一维数组则没有这个功能)
#计算整个数组所有元素的平均值/标准差
a.mean()
a.std()
#计算每一行的平均值/标准差
a.mean(axis=1)
a.std(axis=1)
#计算每一列的平均值/标准差
a.mean(axis=0)
a.std(axis=0)
再来看Pandas二维数组DataFrame,它和我们的Excel十分类似。
以下是其简单操作:
#第一步需要定义字典
salesDict={'购药时间':['2008-01-01 星期五','2018-01-01 星期六','2018-01-06 星期三'],
'社保卡号':['001616528','001616528','001616528'],
'商品编码':[236701,236701,236701],
'商品名称':['强力VC银翘片','清热解毒口服液','感康'],
'销售数量':[6,1,2],
'应收金额':[82.8,28,16.8],
'实收金额':[69,24.64,15]}
salesDf=pd.DataFrame(salesDict)
salesDf
#但由于字典是无序的,如果需要让它按照我们输入的键排列的话,就需要定义有序字典
from collections import OrderedDict
salesOrderedDict=OrderedDict(salesDict)
salesDf=pd.DataFrame(salesOrderDict)
#平均值计算,按每列来求
salesDf.mean()
#运用iloc属性根据位置获取值,前面代表行号,后面代表列号
salesDf.iloc[0,1]
#获取第一行
salesDf.iloc[0,:]
#获取第一列
salesDf.iloc[:,0]
#运用loc属性根据索引值获取值,前面代表行名,后面代表列名
salesDf.loc[0,'商品编码']
#获取第一行
salesDf.loc[0,:]
#获取第一列
salesDf.iloc[:,'商品名称']
#查询范围
#查询某几列
salesDf.[['商品名称'],['销售数量']]
#查询指定连续的列
salesDf.loc[:,'商品名称','销售数量']
#通过条件判断筛选符合条件的行
querySer=salesDf.loc[:,'销售数量']>1
querySer
salesDf.loc[querySer,:]
#查看数据有多少行和列
salesDf.shape
#查看每一列的统计数
salesDf.describe()
下面我们介绍数据分析的基本过程:
总共是5步,分别是提出问题/理解数据/数据清洗/构建模型/数据可视化
首先提出问题:我们打算求数据集:朝阳医院2018年销售数据 的
月均消费次数/月均消费金额/客单价 三个值
再是理解数据
#读取数据
FileNameStr='./朝阳医院2018年销售数据'
xls=pd.ExcelFile(FileNameStr,dtype='object')
salesDf=xls.parse('Sheet1',dtype='object')
接着进行数据清洗:
这个步骤共有6小步,分别是 选择子集/列名重命名/缺失数据处理/数据类型转换/数据排序/异常值处理
#选择子集
subsalesDf=salesDf.loc[0:4,'购药时间':'销售数量']
subsalesDf
#列名重命名 前面是旧列名,后面是新列名,inplace=True是将原数据框变成新数据框,
而False则是创建一个改动的新数据框
colNameDict={'购药时间':'销售时间'}
salesDf.rename(columns=colNameDict,inplace=True)
#缺失数据处理 选取的列数值有缺失就会被删掉
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
#数据类型转换
salesDf['销售数量']=salesDf['销售数量'].astype('float')
salesDf['应收金额']=salesDf['应收金额'].astype('float')
salesDf['实收金额']=salesDf['实收金额'].astype('float')
print('转换后的数据类型:
',salesDf.dtypes)
#分割销售日期 ,将'2008-01-01 星期五'分割,取'2008-01-01'
def splitSaletime(timeColSer):
timeList=[]
for value in timeColSer:
dateStr=value.split('')[0]
timeList.append(dateStr)
timeSer=pd.Series(timeList)
return timeSer
timeSer=salesDf.loc[:,'销售时间']
dateSer=splitSaletime(timeSer)
#修改销售时间这一列的值
salesDf.loc[:,'销售时间']=dateSer
#字符串转换日期
salesDf.loc[:,'销售时间']=pd.to_datetime(salesDf.loc[:,'销售时间'],
format='%Y-%m-%d',
errors='coerce')
#将转换日期过程中不符合日期格式的数值转换而成的空值None删除掉
salesDf=salesDf.dropna(subset=['销售时间','社保卡号'],how='any')
#将数据排序 ascending=True表示升系,False降序
salesDf=salesDf.sort_values(by='销售时间',ascending=True)
#排列后行数顺序会乱,所以要重命名
salesDf=salesDf.reset_index(drop=True)
#异常值处理 通过条件判断筛选出我们想要的数据
querySer=salesDf.loc[:,'销售数量']>0
salesDf=salesDf.loc[querySer,:]
再进行构建模型:
月均消费次数=总消费次数/月份数
(将同一个社保卡号的人同一天的消费算作是以此消费)
#删除重复数据
kpi1Df=salesDf.drop_duplicates(subset=['销售时间','社保卡号'])
#查看kpi1Df总共有多少行,即总消费次数
totalkpi1Df=kpi1Df.shape[0]
#按销售时间排序并重命名
kpi1Df=kpi1Df.sort_value(by='销售时间',ascending=True)
kpi1Df=kpi1Df.reset_index(drop=True)
#获取时间范围
startTime=kpi1Df.loc[0,'销售时间']
endTime=kpi1Df.loc[totalkpi1Df-1,'销售时间']
#计算月份数
days=(endTime-startTime).days
months=days//30
#总消费次数/月份数
kpi1=totalkpi1Df//months
月均消费金额=总消费金额/总月份数
#总消费金额
totalMoney=salesDf.loc[:,'实收金额'].sum()
#总消费金额/总月份数
monthMoney=totalMoney/months
客单价=总消费金额/总消费次数
pct=totalMoney/kpi1
最后一步就是数据可视化,来反映变化趋势。这需要用到matplotlib这个绘图工具了。这个且听下回分解。
在学习这块内容的时候,我在定义完分割函数splitSaletime后,调用函数显示错误的情况,如下图所示:
在大神的帮助下,了解到原因是因为我那一列的数据中含有缺失值为浮点数据类型的数据,所以我就运用dropna函数将其删除...随后成功。
这一块数据分析的内容比较基础,容易理解,也让我掌握了在excel之外进行数据分析的一个技能,而且相比excel,代码记熟后还是用python更舒服~人生苦短,我用python!