当前位置:   article > 正文

如何用python进行数据分析_python数据分析代码

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
  • 2
  • 3
  • 4
  • 5

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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

其实numpy的一维数组的定义和查询和列表是类似的

2.Numpy一维数组与列表的区别

  • numpy 可以进行向量化运算,属于线性代数运算
  • numpy数组中的元素都必须是同一种数据类型,而列表可以是不同的数据类型
# 统计计算  平均值
a.mean()
3.5


# 计算标准差
a.std()
1.118033988749895

# 向量化计算:乘以标量
b = np.array([1,2,3])
c= b*4

c
array([ 4,  8, 12])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

二、二维数据分析

# 导入包
import numpy as np
import pandas as pd
  • 1
  • 2
  • 3

1.用Numpy 定义二维数组

# Numpy 微微数据结构为:Array
# 定义二位数组
a = np.array([     # 这里的array首字母写成小写的a, 前面的Series写成大写S
       [1,2,3,4],
       [5,6,7,8],
       [9,10,11,12]
])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.查询元素

# 获取某行某列中的某个元素
a[0,2]
3


# 获取第一行
a[0,:]  #a[行号,:],注意逗号在前面,冒号在后面;如果位置搞反,会将所有的元素都打印出来
array([1, 2, 3, 4])



# 获取第一列
a[:,0]  # a[:,列号]  注意冒号在前面,逗号在后面,如果位置搞反,会直接报错
array([1, 5, 9])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3.Numpy数轴参数

# Numpy 数轴参数:axis
#如果没有指定数轴参数,会计算整个数组的平均值
a.mean()    # 将所有数值相加除以数据个数
6.5


#按轴计算:axis=1计算每一行, axis=0计算每一列
a.mean(axis=1)  # 每一行的平均值
array([ 2.5,  6.5, 10.5])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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]     # 里面是列表的形式
}  # 外围是大括号 

# 括号记得一定要成对的输入,不要漏写
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.定义有序数据框

# 导入有序字典
from collections import OrderedDict


'''因为是按照哈希函数来存储的,所以很多时候我们认为python中的字典
是无序排序,但是python中有个模块collections自带一个子类OrderedDict,
实现了对字典对象中元素的排序'''

# 定义一个有序字典
salesOrderDict = OrderedDict(salesDict)


# 定义数据框:传入字典,列名
salesDf = pd.DataFrame(salesOrderDict)

salesDf
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

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

# 通过列表来选择某几列的数据
salesDf[['商品名称','销售数量']]   # 注意中间是一个列表
  • 1
  • 2

在这里插入图片描述

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

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,:]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

10.数据集描述统计信息

# 数据集描述统计信息
# 第一步 读取excel数据
fileNameStr = './朝阳医院2018年销售数据.xlsx'
xls = pd.ExcelFile(fileNameStr)
salesDf = xls.parse('Sheet1')  #parse 是解析的意思

# 打印出前3行, 以确保数据运行正常
salesDf.head(3)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

# 查看列的数据类型: dtype
salesDf.loc[:,'销售数量'].dtype
dtype('float64')
  • 1
  • 2
  • 3
#  产看行列数量
salesDf.shape  # shape就是形状
(6578, 7)
  • 1
  • 2
  • 3
# 查看每一列的统计数值
salesDf.describe()
  • 1
  • 2

三、数据分析步骤

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

# 查看有多少行,多少列
salesDf.shape

(6578, 7)

# 查看每一列的数据类型
salesDf.dtypes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

3.数据清洗步骤

  • 选择子集
# 1) 选择子集(本案例不需要选择子集)
# 因为不需要,所以把下行代码注释掉
subSalesDf = salesDf.loc[0:4,'购药时间':'销售数量']
subSalesDf
  • 1
  • 2
  • 3
  • 4

  • 列名重命名
# (2) 列名重命名

# 字典:旧列名和新列名对应关系
colNameDict = {'购药时间':'销售时间'}

'''inplace = False, 数据框本身不会变,而会创建一个改动后新的数据框
默认的inplace是False
inplace = True 数据框本身会改动'''

salesDf.rename(columns = colNameDict,inplace = True)
salesDf.head()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  • 缺失数据处理

‘’'python 中缺失值有三种:

1) python内置的None值

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

  2. 对于数值数据,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)  # 不知道为什么和老师的不太一样 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

以后遇到缺失值无法删除提供了以下几种解决方法:

方法一:

【问】删除缺失值,发现没有删除掉

【答】按这个修改下格式就可以了

[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错误信息。
警告的信息不用管,我们只关注错误类型的信息
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

处理日期

# 购药时间那一列 是由日期+空格+星期几 共同构成,现在需要将这一列字符串分割
# 测试 字符串分割
testlist = '2018-06-03 星期五'.split(' ')
testlist

['2018-06-03', '星期五']

testlist[0]
'2018-06-03'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在源数据中如何处理日期问题

'''定义函数:分割销售日期,获取销售日期
输入: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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
#获取“销售时间”这一列
timeSer=salesDf.loc[:,'销售时间']

#对字符串进行分割,获取销售日期
dateSer=splitSaletime(timeSer)   #应用上面的函数
# 这里一直报错的原因: “'str' object has no attribute 'spilt'”
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意点:有人报错"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'>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
dateSer[0:3] # 查看前三行的数据
  • 1

0 2018-01-01

1 2018-01-02

2 2018-01-06

dtype: object

# 修改销售时间这一列的值
salesDf.loc[:,'销售时间'] = dateSer

salesDf.head()  # 查看修改后的结果
  • 1
  • 2
  • 3
  • 4

字符串转换日期

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

# errors = 'coerce' 如果原始数据不符合日期的格式,转换后的值为空值NaT
# format 是你原始数据中日期的格式
salesDf.loc[:,'销售时间']= pd.to_datetime(salesDf.loc[:,'销售时间'],
                                     format='%Y-%m-%d',
                                     errors='coerce')

salesDf.dtypes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

'''转换日期过程中不符合日期格式的数值会被转换被空值,
这里删除列(销售时间,社保卡号)中为空的行'''

salesDf = salesDf.dropna(subset = ['销售时间','社保卡号'],how ='any')

# 在数据清洗的过程中需要多次删除空值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 排序
print('排序前的数据集')
salesDf.head()
  • 1
  • 2

by: 哪几列排序

ascending = True 表示升序排列,

ascending = False 表示降序排列,

na_position = True 表示排序的时候,把空值放到前列,这样可以比较清晰看到哪些地方又空值

# 按销售日期进行升序排列
salesDf = salesDf.sort_values(by = '销售时间',
                             ascending = True,
                             na_position = 'first')


print('排序后的数据集')
salesDf.head(3)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

# 重命名行名(index):排序后的列索引值是之前的行号,需要修改成从0到N按顺序的索引值
salesDf= salesDf.reset_index(drop=True)
salesDf.head()
  • 1
  • 2
  • 3

# 描述指标:查看出“销售数量”值不能小于0
salesDf.describe()
  • 1
  • 2

通过观察以上描述统计信息我们发现,销售数量有负值,相应的应收金额和实收金额也有负值,这是不符合常理的

通过条件判断筛选出数据

# 删除异常值:通过条件判断筛选出数据
# 查询条件
querySer = salesDf.loc[:,'销售数量'] > 0


# 应用查询条件
print('删除异常值前:', salesDf.shape)
salesDf = salesDf.loc[querySer,:]
print('删除异常值后:', salesDf.shape)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

删除异常值前: (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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

#获取时间范围

# 第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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

月份数: 6

kpi1_I = totalI // monthsI
print('业务指标1:月均消费次数=',kpi1_I)
  • 1
  • 2

业务指标1:月均消费次数= 890

(2) 月均消费金额

totalMoneyF = salesDf.loc[:,'实收金额'].sum()

monthMoneyF = totalMoney / monthsI

print('业务指标2:月均消费金额=', monthMoneyF)
  • 1
  • 2
  • 3
  • 4
  • 5

业务指标2:月均消费金额 = 50668.3516

(3) 客单价

'''totalMoneyF: 总消费金额
   totalI: 总消费次数
'''

pct = totalMoneyF / totalI

print('客单价:', pct)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

客单价:56.9094

-END-


学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习、自动化测试带你从零基础系统性的学好Python!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/385633
推荐阅读
相关标签