赞
踩
大概的学习流程如下,在用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家公司某一天的股价(单位是美元)。其中腾讯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
-END-
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习、自动化测试带你从零基础系统性的学好Python!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/385633
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。