赞
踩
大家好,小编来为大家解答以下问题,python数据分析与应用第2版课后题答案,python数据分析期末大作业选题,今天让我们一起来看看吧!
大概的学习流程如下,在用python进行数据分析的时候通常用的两个包是numpy和pandas
一、一维数据分析
在pandas中的一维数据结构Series, 在numpy中的一维数据结构叫array,
panads的series是基于numpy的array,并且功能更多,必须先掌握numpy的array。
- # 导入numpy包
- >>> import numpy as np
-
- # 导入panads包
- >>> import pandas as pd # 注意不要写成panads
1.Numpy一维数组
- # 定义:一维数组array
- a = np.array([2,3,4,5]) # 必须要在前面加上np
-
- # 以下进行切片查询
- a[0]
- result 2
-
- a[1:3]
- array([3, 4])
-
- for i in a:
- print(i,end = ' ')
- 2 3 4 5
-
- # 查看数据类型dtype
- a.dtype
-
- dtype('int32')
其实numpy的一维数组的定义和查询和列表是类似的
2.Numpy一维数组与列表的区别
- # 统计计算 平均值
- a.mean()
- 3.5
-
-
- # 计算标准差
- a.std()
- 1.118033988749895
-
- # 向量化计算:乘以标量
- b = np.array([1,2,3])
- c= b*4
-
- c
- array([ 4, 8, 12])
3.panads 一维数据结构
- # 定义:pandas 一维数据结构:Series
- # 存放6家公司某一天的股价(单位是美元)学python需要先学c么。其中腾讯427.4港元兑换成54.74美元
- # 这里的Series开头一定要写成大写S,否则报错
-
-
- stockS= pd.Series([54.74,190.9,173.14,1050.3,181.86,1139.49],
- index = ['腾讯','阿里巴巴','苹果','谷歌','Facebook','亚马逊'])
-
- stockS # 注意python是区分大小写的,写成stocks直接报错
-
- 腾讯 54.74
- 阿里巴巴 190.90
- 苹果 173.14
- 谷歌 1050.30
- Facebook 181.86
- 亚马逊 1139.49
- dtype: float64
4.获取描述统计信息
- # 获取描述统计信息
- # 得到的信息基本何在excel中做描述统计分析的信息是一致的
- 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
5.向量相加
- # 向量化运算:向量相加
- 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 # 类似于关键词命名,相同关键词的值相加
-
- a 11.0
- b 22.0
- c NaN
- d NaN
- e NaN
- f NaN
- dtype: float64
-
-
- # 看到以上结果除了a和b,其他的均为空值,删除空值有两种方法
- # 方法一:删除缺失值
- s3.dropna()
-
- a 11.0
- b 22.0
- dtype: float64
-
-
- # 方法二:将缺失值进行填充
- s3 = s1.add(s2, fill_value = 0) # 这里是指将e和f未能对应的两个值赋为0
- s3
-
- a 11.0
- b 22.0
- c 3.0
- d 4.0
- e 30.0
- f 40.0
- dtype: float64
二、二维数据分析
- # 导入包
- import numpy as np
- import pandas as pd
1.用Numpy 定义二维数组
- # Numpy 微微数据结构为:Array
- # 定义二位数组
- a = np.array([ # 这里的array首字母写成小写的a, 前面的Series写成大写S
- [1,2,3,4],
- [5,6,7,8],
- [9,10,11,12]
- ])
2.查询元素
- # 获取某行某列中的某个元素
- a[0,2]
- 3
-
-
- # 获取第一行
- a[0,:] #a[行号,:],注意逗号在前面,冒号在后面;如果位置搞反,会将所有的元素都打印出来
- array([1, 2, 3, 4])
-
-
-
- # 获取第一列
- a[:,0] # a[:,列号] 注意冒号在前面,逗号在后面,如果位置搞反,会直接报错
- array([1, 5, 9])
3.Numpy数轴参数
- # Numpy 数轴参数:axis
- #如果没有指定数轴参数,会计算整个数组的平均值
- a.mean() # 将所有数值相加除以数据个数
- 6.5
-
-
- #按轴计算:axis=1计算每一行, axis=0计算每一列
- a.mean(axis=1) # 每一行的平均值
- array([ 2.5, 6.5, 10.5])
4. Pandas数据框(DataFrame)
有一个注意点:如果重新打开代码的时候,继续执行未执行完的代码,,可能会报错未导入包,所以在代码的开头重新导入包即可
- import numpy as np
- import pandas as pd
-
- # pandas 二维数组:数据框(dataframe)
- # 第一步:定义一个字典,映射列名与对应列的值
- 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] # 里面是列表的形式
- } # 外围是大括号
-
- # 括号记得一定要成对的输入,不要漏写
5.定义有序数据框
- # 导入有序字典
- from collections import OrderedDict
-
-
- '''因为是按照哈希函数来存储的,所以很多时候我们认为python中的字典
- 是无序排序,但是python中有个模块collections自带一个子类OrderedDict,
- 实现了对字典对象中元素的排序'''
-
- # 定义一个有序字典
- salesOrderDict = OrderedDict(salesDict)
-
-
- # 定义数据框:传入字典,列名
- salesDf = pd.DataFrame(salesOrderDict)
-
- salesDf
6. iloc 属性用于根据位置查询值
- # 查询数据:iloc属性用于根据位置获取值
- # 查询第一行第二列的元素
- salesDf.iloc[0,1] # 注意最前面的那个序列号不算,是Python自动赋予的
- '001616528'
-
- # 获取第一行的所有元素
- salesDf.iloc[0,:]
-
- 购药时间 2018-01-01 星期五
- 社保卡号 001616528
- 商品编码 236701
- 商品名称 强力VC银翘片
- 销售数量 6
- 应收金额 82.8
- 实收金额 69
- Name: 0, dtype: object
-
-
- # 获取第一列的所有元素
- salesDf.iloc[:,0]
-
- 0 2018-01-01 星期五
- 1 2018-01-02 星期六
- 2 2018-01-06 星期三
- Name: 购药时间, dtype: object
7. loc 属性用于根据索引查询值
- # 查询数据:loc属性用于根据索引获取值
- # 查询第一行第一列的元素
- salesDf.loc[0,'商品编码']
- 236701
-
-
- # 获取第一行
- salesDf.loc[0,:] # 注意逗号和冒号的顺序
-
- 购药时间 2018-01-01 星期五
- 社保卡号 001616528
- 商品编码 236701
- 商品名称 强力VC银翘片
- 销售数量 6
- 应收金额 82.8
- 实收金额 69
- Name: 0, dtype: object
-
-
-
- # 获取”商品名称” 这一列
- salesDf.loc[:,'商品名称']
-
- 0 强力VC银翘片
- 1 清热解毒口服液
- 2 感康
- Name: 商品名称, dtype: object
-
-
- # 简单的方法,直接获取“商品名称”这一列
- salesDf['商品名称']
-
- 0 强力VC银翘片
- 1 清热解毒口服液
- 2 感康
- Name: 商品名称, dtype: object
8.数据框复杂查询:切片功能
- # 通过列表来选择某几列的数据
- salesDf[['商品名称','销售数量']] # 注意中间是一个列表
- # 通过切片功能,获取指定范围的列
- salesDf.loc[:,'购药时间':'销售数量']
9.数据框复杂查询:条件判断
- # 通过条件判断筛选
- # 第一步:构建查询条件
- querySer = salesDf.loc[:,'销售数量'] > 1
-
- type(querySer) #是pandas的包的series的一维数组
- pandas.core.series.Series
-
- querySer
- 0 True
- 1 False
- 2 True
- Name: 销售数量, dtype: bool
-
-
- # 通过构建的条件进行筛选
- salesDf.loc[querySer,:]
10.数据集描述统计信息
- # 数据集描述统计信息
- # 第一步 读取excel数据
- fileNameStr = './朝阳医院2018年销售数据.xlsx'
- xls = pd.ExcelFile(fileNameStr)
- salesDf = xls.parse('Sheet1') #parse 是解析的意思
-
- # 打印出前3行, 以确保数据运行正常
- salesDf.head(3)
- # 查看列的数据类型: dtype
- salesDf.loc[:,'销售数量'].dtype
- dtype('float64')
- # 产看行列数量
- salesDf.shape # shape就是形状
- (6578, 7)
- # 查看每一列的统计数值
- salesDf.describe()
三、数据分析步骤
1.提出问题
‘’'从销售数据中分析出以下业务指标:
(1) 月均消费次数
(2) 月均消费金额
(3) 客单价
(4)消费趋势 ‘’’
2.理解数据
- import pandas as pd
-
- '''路径中不要有英文和特殊符号,不然会路径报错,最好将
- 文件放到一个简单的英文路径下'''
-
- # excel文件路径,路径中的 ./表示在当前的notebook所在文件夹路径
- fileNameStr = './朝阳医院2018年销售数据.xlsx'
-
-
- '''使用pandas的read_excel 函数读取excel数据
- 参数sheet_name: 数据在excel 里的哪个sheet 下面,这块就写在该sheet的excel里的名称
- 参数的type= str 统一先按照字符串读入, 之后再转换'''
-
-
- salesDf = pd.read_excel(fileNameStr, sheet_name = 'Sheet1',dtype = str)
- dtype = 'object' 的含义是会统一按照字符串的类型读取数据
-
- 实收金额是应收金额进行一定折扣后的价格
-
- # 打印出前几行,查看基本信息,确保数据运行正常
- salesDf.head()
- # 查看有多少行,多少列
- salesDf.shape
-
- (6578, 7)
-
- # 查看每一列的数据类型
- salesDf.dtypes
3.数据清洗步骤
- # 1) 选择子集(本案例不需要选择子集)
- # 因为不需要,所以把下行代码注释掉
- subSalesDf = salesDf.loc[0:4,'购药时间':'销售数量']
- subSalesDf
- # (2) 列名重命名
-
- # 字典:旧列名和新列名对应关系
- colNameDict = {'购药时间':'销售时间'}
-
- '''inplace = False, 数据框本身不会变,而会创建一个改动后新的数据框
- 默认的inplace是False
- inplace = True 数据框本身会改动'''
-
- salesDf.rename(columns = colNameDict,inplace = True)
- salesDf.head()
‘’'python 中缺失值有三种:
1) python内置的None值
在pandas 中,将缺失值表示为NA, 表示不可用not available
对于数值数据,pandas使用浮点值NAN(Not a number)表示缺失数据
后面出来数据,如果遇到错误:有float错误,就是有缺失值,需要处理掉
所以,缺失值有三种:None NA NaN’‘’
- print('删除缺失值前文件大小',salesDf.shape)
- 删除缺失值前文件大小 (6578, 7)
-
- salesDf.replace(to_replace='nan',value=np.nan, inplace=True)
- 之前一直没有办法删除缺失值,原因是这里的空缺值存储的是字符串形式,这个字符串的值是'NAN',而不是python缺失值的类型,所以先替换成'NaN'
-
-
- # 删除列(销售时间,社保卡号)中为空的行
- # how = 'any' 在给定的任何一列中有缺失值就删除
- salesDf = salesDf.dropna(subset = ['销售时间','社保卡号'], how = 'any')
-
-
- print('删除缺失后大小',salesDf.shape)
- 删除缺失后大小 (6575, 7) # 不知道为什么和老师的不太一样
以后遇到缺失值无法删除提供了以下几种解决方法:
方法一:
【问】删除缺失值,发现没有删除掉
【答】按这个修改下格式就可以了
[https://stackoverflow.com/questions/39339935/pandas-dropping-rows-with-missing-data-not-working-using-isnull-notnull](https://link.zhihu.com/?target=
这个方法不是很实用,对于数据少量的情况下可以用
方法二:
【可能原因2】排查了一下确实是那个nan的问题。我数据分析的专用环境是nb,但是起先没切换过去,用了默认的base环境。切换kernal后就正常显示了NaN,并能dropna空值了。
进一步比对了一下两个环境,发现base环境的pandas和xlrd版本更旧一点点,更新之后就也可以正常使用了。
字符串转换为数值(浮点数)
- # 字符串转换为数值(浮点型) 因为前面设置的时候销售数量、应收金额、实收金额没有设置为整数
- salesDf['销售数量'] = salesDf['销售数量'].astype('float')
- salesDf['应收金额'] = salesDf['应收金额'].astype('float')
- salesDf['实收金额'] = salesDf['实收金额'].astype('float')
- print('转换后的数据类型:\n', salesDf.dtypes)
-
-
- '''
- 运行后,会报警告settingWithWarning
- 一般信息有两列, 一类是warning警告信息,一类是Error错误信息。
- 警告的信息不用管,我们只关注错误类型的信息
- '''
处理日期
- # 购药时间那一列 是由日期+空格+星期几 共同构成,现在需要将这一列字符串分割
- # 测试 字符串分割
- 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] # 是split 不是spilt
- timeList.append(dateStr)
-
- #将列表转行为一维数据Series类型
- timeSer=pd.Series(timeList)
- return timeSer
- #获取“销售时间”这一列
- timeSer=salesDf.loc[:,'销售时间']
-
- #对字符串进行分割,获取销售日期
- dateSer=splitSaletime(timeSer) #应用上面的函数
- # 这里一直报错的原因: “'str' object has no attribute 'spilt'”
注意点:有人报错"float object has no attribute split"
是因为有空值,pandas中空值是浮点型,在没有去除空值的情况下,就切割
可能是因为是浮点型,其实是会参与运算
那None和NaN有什么区别呢:
None是Python的一种数据类型,NaN是浮点类型 两个都用作空值
- # None 和NaN的区别
- print('None的数据类型', type(None))
-
- from numpy import NaN
- print('NaN的数据类型',type(NaN))
-
-
- None的数据类型 <class 'NoneType'>
- NaN的数据类型 <class 'float'>
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
- '''转换日期过程中不符合日期格式的数值会被转换被空值,
- 这里删除列(销售时间,社保卡号)中为空的行'''
-
- salesDf = salesDf.dropna(subset = ['销售时间','社保卡号'],how ='any')
-
- # 在数据清洗的过程中需要多次删除空值
- print('排序前的数据集')
- salesDf.head()
by: 哪几列排序
ascending = True 表示升序排列,
ascending = False 表示降序排列,
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()
- # 描述指标:查看出“销售数量”值不能小于0
- salesDf.describe()
通过观察以上描述统计信息我们发现,销售数量有负值,相应的应收金额和实收金额也有负值,这是不符合常理的
通过条件判断筛选出数据
- # 删除异常值:通过条件判断筛选出数据
- # 查询条件
- querySer = salesDf.loc[:,'销售数量'] > 0
-
-
- # 应用查询条件
- print('删除异常值前:', salesDf.shape)
- salesDf = salesDf.loc[querySer,:]
- print('删除异常值后:', salesDf.shape)
删除异常值前: (6549, 7)
删除异常值后: (6506, 7)
(1) 月均消费次数
业务指标 1: 月均消费次数 = 总消费次数/月份数
获取总消费次数
- '''
- 总消费次数: 同一天内,同一个人发生的所有消费算作一次消费
- 根据列名(销售时间,社区卡号),如果这两个列值同时相同,只保留1条,将重复的数据删除
- '''
-
-
- # 用 drop_duplicates 删除重复数据,subset里面盛放要删除列的名称
- kpi1_Df = salesDf.drop_duplicates(
- subset = ['销售时间','社保卡号'])
-
-
-
- kpi1_Df.shape # shape是返回一个列表,返回行和列的数量,所以取第一个值,就是行数量
- totalI = kpi1_Df.shape[0]
-
-
- print('总消费次数=',totalI)
-
- 总消费次数= 5342
#获取时间范围
- # 第2步:获取时间范围
- # 最小时间值
- startTime = kpi1_Df.loc[0,'销售时间']
- # 最大时间值
- endTime = kpi1_Df.loc[totalI-1,'销售时间']
-
- print(startTime, endTime)
- 2018-01-01 00:00:00 2018-07-19 00:00:00
-
-
- #第3步:计算月份数
- #天数
- daysI=(endTime-startTime).days
- #月份数: 运算符“//”表示取整除
- #返回商的整数部分,例如9//2 输出结果是4
- monthsI=daysI//30
- print('月份数:',monthsI)
月份数: 6
- kpi1_I = totalI // monthsI
- print('业务指标1:月均消费次数=',kpi1_I)
业务指标1:月均消费次数= 890
(2) 月均消费金额
- totalMoneyF = salesDf.loc[:,'实收金额'].sum()
-
- monthMoneyF = totalMoney / monthsI
-
- print('业务指标2:月均消费金额=', monthMoneyF)
业务指标2:月均消费金额 = 50668.3516
(3) 客单价
- '''totalMoneyF: 总消费金额
- totalI: 总消费次数
- '''
-
- pct = totalMoneyF / totalI
-
- print('客单价:', pct)
客单价:56.9094
这份完整版的Python全套学习资料已经上传,朋友们如果需要可以点击链接免费领取或者滑到最后扫描二v码【保证100%免费
】
需要的话可以点击这里
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。