-- coding: utf-8 --
"""
Created on Fri Sep 25 23:07:47 2020
@author: liangfeng
"""
x-y
xy
runcell(0, 'C:/Users/liangfeng/test/未命名7.py')
x/y
x//y
7/4
7//4
7%4
32
x='谁说菜鸟不会数据分析(入门篇)'
y="谁说菜鸟不会数据分析(入门篇)"
z='''谁说菜鸟不会数据分析(入门篇)'''
o="""谁说菜鸟不会数据分析(入门篇)"""
print(srt1 + '' + str2)
str1='谁说菜鸟不会数据分析'
str2='python篇'
print(str1 + '' + str2)
print('' * 1)
print('' * 2)
print('' * 3)
'13800138001'[0:3]
'13800138001'[-11:-8]
'13800138001'[:3]
'13800138001'[3:]
string='谁说菜鸟不会数据分析-python篇'
判断字符串是否以
'谁说菜鸟不会数据分析'开头
string.startswith('谁说菜鸟不会数据分析')
string.startswith('python篇')
string.find('python篇')
string.find('入门篇')
string.replace('python篇','入门篇')
introductionformat='大家好,我是%s,%d岁,身高%fcm'
introductionformat % ('KEN',18,175.35)
'%+f'%(3.14159)
'%+3f'%(3.14159)
'%+10f'%(3.14159)
'%.2f'%(3.14159)
'%.2f%%'%(0.314159100)
r=123321
r
r/(321-123)
age = [21,22,23,24,25]
age
name = ['KEN','JOHN','JIMI']
name
age[0]
age[2]
name[0]
name[2]
age[0:2]
name[0:2]
21 in age
'JIMI' in name
28 in age
'Test' in name
allName.append('刘一')
allName.append('陈二')
allName
allName = []
往列表中增加数据
allName.append('刘一')
allName.append('陈二')
allName
allName[]
name1=['张三','李四','王五']
name2=['赵六','孙七','周八']
allName.extend(name1)
allName=[]
name1=['张三','李四','王五']
name2=['赵六','孙七','周八']
allName.extend(name1)
allName
allName=[]
name1=['张三','李四','王五']
name2=['赵六','孙七','周八']
allName.extend(name1)
allName.extend(name2)
allName
allName[0]='刘1'
allName=[]
allName[0]='刘1'
allName=[]
name1=['张三','李四','王五']
name2=['赵六','孙七','周八']
allName.extend(name1)
allName.extend(name2)
allName[0]='刘1'
allName
allName[1:3]=['陈2','张3']
allName
8删除
按照位置删除列表中的数据
删除0也是第一位的数据
del allName[0]
按照列值删除列表中的数据
删除列表中的值为'陈2'的数据
allName.remove('陈2')
3.3.1 字典
data = {}
data
data = {
'name':['KEN','John','JIMI'],
'age':['21','22','23']
}
data
data['name']
访问 name 这一列
data['name']
访问age这一列
data['age']
通过keys函数,获取字典中的所有键
data.keys()
通过values函数,获取字典中的所有值
data.values()
5查找
判断age 是否在字典data的键中
'age' in data.keys()
判断gender 是否在字典data的键中
'gender' in data.keys()
6增加
修改字典data的键gender的值
data['gender'] = ['male','male','male']
data
7修改
修改字典data的键gender的值
data['gender'] = ['male','male','male']
data
8删除
删除字典 data 的键 age
del data['age']
data
3.3.3序列
import pandas as pd
定义序列,通过data 参数指定数据,然后将定义好的序列,赋值给a
a = pd.Series(
data = ['a',True,3])
a
通过 index 参数 ,指定索引
x = pd.Series(
data = ['a',True,3],
index =['first','second','third']
)
x
访问
通过默认索引,访问序列中特定的位置的数据
x[1]
通过自定义索引,访问序列中特定位置的值
x['second']
通过切片的方式,访问序列中多个位置的值
x[1:3]
通过指定位置的列表,按指定位置值返回
两个中括号的用法:
1,外面的中括号用作取值
2,里面的中括号是一个列表,取多个位置的值
x[[2,0,1]]
5查找
使用 in 关键词,未指定index 还是values
默认判断'first' 是否存在x的索引中,
'first' in x
使用 in 关键词
判断'first'是否在序列索引中,
'first' in x.index
使用 in 关键词
判断 '2'是否在序列x值中
'2' in x.values
判断一个集合,是否在另外一个集合的子集,可以使用isin函数
判断 True,'a' 是否都在x值中
x.isin([True,'a'])
增加
append方法,可以追加一个序列
ns = pd.Series(['2'])
x.append(ns)
需要修改x,则需要对x进行重新赋值
x = x.append(ns)
x
7修改
根据索引,进行修改
x['first'] = '入门篇'
根据多个索引进行修改,多个索引引用列表进行表示
x[['second','third']] = ['工具篇','Python篇']
8删除
使用默认索引,对x值重新赋值
x = pd.Series(
['1','2','3']
)
x
x.drop(0)
根据多个索引 删除
x.drop([0,1])
使用自定义索引,对x重新赋值
x = pd.Series(
['1','2','3'],
index=['first','second','third'])
x
根据一个索引删除
x.drop('first')
x
根据多个索引,删除
x.drop(['first','second'])
x
3.3.4数据库
定义数据框,通过data 参数,指定数据
import pandas as pd
dataFrame = pd.DataFrame(
data = {
'name':['KEN','John','JIMI'],
'age' :['21','22','23']
}
)
dataFrame
定义数据框,通过index 参数 ,指定索引
字典里面的索引写法
data = {
'name':['KEN','John','JIMI'],
'age' :['21','22','23'],
'index' : ['first','sencond','third']
}
数据框里面的索引写法
dataFrame = pd.DataFrame(
data = {
'name':['KEN','John','JIMI'],
'age' :['21','22','23']
},
index=['first','sencond','third']
)
dataFrame
定义数据框,通过data参数,指定数据
通过 column 参数,指定使用列与顺序
dataFrame = pd.DataFrame(
data = {
'name':['KEN','John','JIMI'],
'age' :['21','22','23'],
'other':['a','b','c']
},
#index=['first','sencond','third']
columns = ['name','age']#指定按name,age两列顺序排
)
dataFrame
访问可以按列名,行号,索引的方式进行访问
按列访问,访问一列
dataFrame['age']
按列访问,访问多列,这里有两个中括号
第一个中括号表示从数据框中按列取值
第二个中括号是个列表,表示有多列
dataFrame[['age','name']]
按行序号访问单行
返回来一个以列名为索引的序列
dataFrame = pd.DataFrame(
data = {
'name':['KEN','John','JIMI'],
'age' :['21','22','23']
},
index=['first','sencond','third']
)
dataFrame
dataFrame.iloc[2]#默认索引
dataFrame.loc['sencond']#自定义索引
5查找
6增加
定义数据框,通过data参数指定数据
nDataFrame = pd.DataFrame(
data = {
'name':['KEN','John','JIMI'],
'age' :['21','22','23']
}
)
将nDataFrame 追加到 dataFrame 中
dataFrame.append(nDataFrame)
对原来的数据框重新赋值,保存追加后数据
dataFrame=dataFrame.append(nDataFrame)
dataFrame
增加列
注意新增加列的行数和数据框的行数一致
dataFrame['class']=[1,2,3,4,5,6]
dataFrame
7修改(列名,行索引,值)
重新生成数据框
dataFrame=pd.DataFrame(
data={
'age':['21','22','23'],
'name':['KEN','john','JIMI']
}
)
dataFrame
获取列名
dataFrame.columns
重新设置列名
dataFrame.columns=['Age','Name']
dataFrame
获取行索引
dataFrame.index
修改行索引
dataFrame.index=['1','2','3']
dataFrame
修改具体某行某列的值
获取索引为1,列名为Name的位置具体值
dataFrame.at['1','Name']
dataFrame.at['1','Name']='KENNY'
dataFrame
8删除
根据行索引,删除行
dataFrame.drop(1,axis=0)
dataFrame
根据列名,删除列
dataFrame.drop('Age',axis=1)
dataFrame
3.4向量运算
生成一个数据框data,通过data参数指定数据
import pandas as pd
data = pd.DataFrame(
data={
'A':[1,3,5,7,9]
}
)
data
平方计算
data['B']=data.A.pow(2)
加法
data['add']=data.A + data.B
减法
data['sub'] = data.B - data.A
乘法
data['mul'] = data.B * data.A
除法
data['div'] = data.B / data.A
3.5 for 循坏
for i in [1,2,3,4]:
print(i)
生成一个数据框data,里面只有一列
import pandas as pd
data = pd.DataFrame(
data={
'A':[1,3,5,7,9]
}
)
遍历A列
把A列中的每个值依次赋值给a
a是个自定义变量名,可换为其他变量名
for a in data['A']:
#输出a
print(a)
定义一个空的列表
用于保存A的平方的结果
B = []
for a in data['A']:
#把aa的结果追加到B中
B.append(aa)
在数据框data中,增加B列
data['B']=B
data
遍历数据框data每一行
index 为iterrows 函数返回每一行的索引
r 为iterrows 函数,返回每一行的值
('-----')是一个以列名为索引的序列
for index,r in data.iterrows():
print(index)
print(r)
print('-------------')
定义一个空的列表C
用于保存A列 + B列的结果
c = []
for index,r in data.iterrows():
#把A+B的结果追加到C中
c.append(r['A']+r['B'])
#在数据框中 data 中增加c列
data['c']=c
data
data['D']=data['A']+data['B']
第四章数据处理
4.1.4 CSV文件导入
将4.csv文件的数据导入到data变量
import pandas as pd
data =pd.read_csv('D:/曾海峰/谁说菜鸟不会数据分析(Python篇)/数据源/PDABook/第四章/4.1.1 数据导入/1.csv',engine='python'
)
data
5.txt文件导入(记得列名参数,sep分隔符,encoding编码,路径有中英文,设置engine)
将2.csv文件的数据导入到data变量
import pandas as pd
data = pd.read_table('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.1.1 数据导入\2.txt',
engine='python',
names=['name','age'],
sep=',',
encoding='UTF8'
)
data
6.excel文件导入
将3.xlsx中的数据导入data数据,设置参数sheet_name为要读取sheet名
import pandas as pd
data = pd.read_excel('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.1.1 数据导入\3.xlsx',
sheet_name='data'
)
data
4.1.2数据导出
定义一个数据框data
import pandas as pd
data = pd.DataFrame(
data={
'name':['KEN','john','JIMI'],
'age':[21,22,23]
}
)
data
调用to_csv函数,将数据保存到data1.csv文件中
data.to_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.1.1 数据导入\data1.csv',
index=False)#index='False'取消索引
4.2数据清洗
4.2.1数据排序
import pandas as pd
data = pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.2.1 数据排序\数据排序.csv',
engine='python',encoding='utf8'
)
data
根据年龄升序、性别降序,对数据进行排序
sortData = data.sort_values(
by = ['年龄','性别'],
ascending=['True','False']
)
sortData
4.2.2重复数据处理
import pandas as pd
data = pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.2.2 重复数据处理\重复值.csv',
engine='python',encoding='utf8')
data
找出行重复值数据位置
dIndex = data.duplicated()#duplicated函数返回来一个序列
dIndex
根据指定性别列,找出重复的位置
dIindex=data.duplicated(['性别'])
dIindex
把返回值为True的行选择出来
达到将重复值数据提取出来的目的
daa=data[data.duplicated()]
daa
直接删除重复值,默认根据所有列进行删除
cdata = data.drop_duplicates()
cdata
4.2.2缺失数据处理
import pandas as pd
data= pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.2.3 缺失值处理\常见缺失值.csv',
engine='python',encoding='utf8')
data
使用消费的均值填充缺失值
data['消费']=data.消费.fillna(data.消费.mean())
data
删除缺失值
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.2.3 缺失值处理\常见缺失值.csv',
engine='python',encoding='utf8')
data
直接删除缺失值
cdata=data.dropna()
cdata
4.2.4空格数据处理
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.2.4 空格值处理\空格值.csv',
engine='python',encoding='utf8')
data
去除字符串的前后的空格
data['name']=data['name'].str.strip()
data
4.3数据转换
4.3.1数值转字符
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.3.1 数值转字符\数值转字符.csv',
engine='python',encoding='utf8')
data
获取数据框所有列的数据类型
data.dtypes
获取电话号码列的数据类型
data.电话号码.dtypes
将电话号码列转换为字符型数据(整数为:int ,小数为:float,字符型为int)
data['电话号码']=data.电话号码.astype(str)
data.电话号码.dtypes
4.3.2字符转数值
data['数值电话号码']=data.电话号码.astype(float)
data.数值电话号码.dtype
4.3.3 字符转时间
pandas.to_datetime(arg,format) arg:字符型时间格式的列,format:时间格式:%Y-年,%m-月,%d-日,%H-时,%M-分,%S-秒
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.3.3 字符转时间\字符转时间.csv',
engine='python',encoding='utf8')
data
data.注册时间.dtype
将"注册时间"这一列,转化为时间类型的数据
然后把时间类型的数据添加为数据框中的"时间列"
data['时间']=pd.to_datetime(data.注册时间,
format='%Y/%m/%d'
)
data['时间'].dtype
data
时间格式化转换
pandas.series.dt.strftime(format),
data['年月']=data.时间.dt.strftime('%Y-%m')
4.4数据抽取(字段拆分/记录抽取/随机抽样)
4.4.1字段拆分
1按照位置拆分-pandas.Series.str.slice(start,stop),start:开始索引,stop:结束索引,只用字符型数据才能使用slice函数
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.4.1 字段拆分\字段拆分.csv',
engine='python',encoding='utf8'
)
data
将数值型电话号码列,转化为字符型
data['tel']=data['tel'].astype(str)
data.tel.dtypes
运营商
bands=data['tel'].str.slice(0,3)
地区
areas=data['tel'].str.slice(3,7)
号码段
nums=data['tel'].str.slice(7,11)
更新数据,将运营商、地区、号码段的列添加到数据框中
data['bands']=bands
data['areas']=areas
data['nums']=nums
2按照分隔符拆分:pandas.Series.str.split(pat='',n=-1,expand=Flase),pat-分隔符,默认为空格,n,分割为多少列,-1代表返回来所有分割列,expand:是否展开数据框,默认是flase,一般设置为True
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.4.1 字段拆分\分隔符.csv',
engine='python',encoding='utf8'
)
使用空格符将商品的名称拆分为品牌与型号,因为第一个空格之前是商品的品牌
第一个空格之后是商品的型号,所以第二个参数设置为1
第三个参数设置为True,使用数据框返回结果
newData=data['name'].str.split('',1,True)
重命名每一列的名称
newData.columns=['band','name1']
时间属性抽取 year,month,day,hour,minute,second,weekday
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.4.1 字段拆分\时间属性.csv',
engine='python',encoding='utf8'
)
把注册时间列转为时间类型的数据,然后赋值给'时间'这一列
data['时间']=pd.to_datetime(
data.注册时间,
format='%Y/%m/%d %H:%M:%S'
)
抽取时间各种属性,新增到对应的列中
data['时间.年']=data['时间'].dt.year
data['时间.月']=data['时间'].dt.month
data['时间.周']=data['时间'].dt.weekday
data['时间.日']=data['时间'].dt.day
data['时间.时']=data['时间'].dt.hour
data['时间.分']=data['时间'].dt.minute
data['时间.秒']=data['时间'].dt.second
data
4.4.2 记录抽取(关键词抽取/空值抽取/数据范围抽取/时间范围抽取/组合条件抽取)
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.4.2 记录抽取\记录抽取.csv',
engine='python',encoding='utf8'
)
data
关键词抽取pandas.series.str.contains(pat,case=True,na=NaN)
1根据关键词字段抽取数据记录
fData=data[data.title.str.contains('台电',na=False)]
data[fData]
2空值抽取
抽取商品标题为空值的数据记录
fData=data[data.title.isnull()]
3数据范围抽取
单条件比较运算
fData=data[data.comments>10000]
根据范围值抽取数据记录
fData=data[data.comments.between(1000,10000)]
时间范围抽取
把上线时间ptime列,转为时间类型数据
import pandas
data['ptime']=pandas.to_datetime(
data.ptime,
format='%Y-%m-%d')
从datetime模块中,引入datetime时间类型的构造函数
定义时间1,2015年01月01日
from datetime import datetime
dt1=datetime(
year=2015,
month=1,
day=1
)
dt2=datetime(
year=2015,
month=12,
day=1
)
介于2015年1-12月之间的数据
fData=data[(data.ptime>=dt1)&(data.ptime<=dt2)]
5组合条件抽取非台积电
~为取反
dData=data[~data.title.str.contains('台电',na=False)]
抽取评论数大于等于1000,小于等于10000,并且标题包含小米的商品记录数
fData=data[
(data.comments>=1000)&(data.comments<=10000)&data.title.str.contains('小米',na=False)]
4.4.3随机抽样(简单抽样,分层抽样,系统抽样)
简单抽样-重复抽样/非重复抽样
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.4.3 随机抽样\随机抽样.csv',
engine='python',encoding='utf8'
)
按个数抽样
sData=data.sample(n=3)
按百分比抽样
sData=data.sample(frac=0.2)
是否放回抽样
sData=data.sample(n=3,replace=True)
4.5数据合并
4.5.1记录合并
import pandas as pd
data1=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.5.1 记录合并\台电.csv',
engine='python',encoding='utf8'
)
data2=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.5.1 记录合并\小米.csv',
engine='python',encoding='utf8'
)
data3=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.5.1 记录合并\苹果.csv',
engine='python',encoding='utf8'
)
data=pandas.concat([data1,data2,data3])
如果要合并的数据具有不同列
data=pandas.concat([
data1[['id','comments']],
data2[['comments','title']],
data3[['id','title']]
]
)
data
4.5.2字段合并
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.5.2 字段合并\字段合并.csv',
engine='python',encoding='utf8'
)
将整个数据框都转为字符型
data=data.astype(str)
将band,area,num列合并为一个新列
tel=data['band']+data['area']+data['num']
将新列加入到数据框中
data['tel']=tel
4.5.3字段匹配(类似inner join)
import pandas as pd
items=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.5.3 字段匹配\商品名称.csv',
engine='python',encoding='utf8')
price=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.5.3 字段匹配\商品价格.csv',
engine='python',encoding='utf8')
内连接-inner join
默认内连接,只保留条件相等的条件
itemsprice=pandas.merge(
items,price,left_on='id',right_on='id')
左连接-left join
itemsprice=pandas.merge(
items,price,left_on='id',right_on='id',how='left')
3右连接-right join
itemsprice=pandas.merge(
items,price,left_on='id',right_on='id',how='right')
外连接 outer join
itemsprice=pandas.merge(
items,price,left_on='id',right_on='id',how='outer')
4.6数据计算
4.6.1 简单计算
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.6.1 简单计算\单价数量.csv',
engine='python',encoding='utf8')
data['total']=data.price*data.num
4.6.2时间计算
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.6.2 时间计算\时间计算.csv',
engine='python',encoding='utf8')
把字符窜的注册时间列,转为时间类型的时间列
import pandas
data['时间']=pandas.to_datetime(
data.注册时间,
format='%Y/%m/%d')
注册天使=当前天数减去注册时间
from datetime.datetime import now-此代码有问题
from datetime import datetime
now = datetime.now()
data['注册天数']=now-data['时间']
把时间间隔的数据类型简化,只保留天数,对于时,分,秒的间隔去掉
data['注册天数']=data['注册天数'].dt.days
4.6.3 数据标准化
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.6.3 数据标准化\标准化.csv',
engine='python',encoding='utf8'
)
0-1标准化
data['消费标准化']=round(
(data.消费-data.消费.min()
)/(data.消费.max()-data.消费.min()
),2
)
4.6.4数据分组
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第四章\4.6.4 数据分组\数据分组.csv',
engine='python',encoding='utf8')
确认cost列中最小值
data.cost.min()
确认cost列中最大值
data.cost.max()
cut函数分段区间默认为左开放,右封闭,而cost列中值最小为2
最大值为100,组距为20
为了使让区间整齐对齐-并且包含2-100内所有的数值,
所有设置了bins参数列表最小值0,最大值100
bins=[0,20,40,60,80,100]
data['cut']=pandas.cut(
data.cost,bins)
区间闭合
如果要设置右区间为开放
那[2,100]内的100这个数字,将无法包含在[0,100]中
为了让100也落在这个区间中,需要增加一个区间为[100,120]
其中,120是在100基础上增加的步长20,目的是让区间看取来整齐
bins=[0,20,40,60,80,100,120
]
data['cut']=pandas.cut(
data.cost,
bins,
right=False)
3自定义标签
bins=[0,20,40,60,80,100,120
]
设置自定义标签,注意个数要和区间个数以及顺序都一一对应
customLabels=['0到20','20到40','40到60','60到80','80到100','100到120'
]
data['cut']=pandas.cut(
data.cost,
bins,
right=False,labels=customLabels)
第五章
5.2 基本统计分析
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.2 基本统计分析\描述性统计分析.csv',
engine='python',encoding='utf8')
描述性统计分析
data.sales.describe()
计数
data.sales.count()
最大值
data.sales.max()
最小值
data.sales.min()
求和
data.sales.sum()
均值
data.sales.mean()
方差
data.sales.var()
标准差
data.sales.std()
百分位数,本例求排在30%的位数
data.sales.quantile(0.3,interpolation='nearest')
5.3 分组分析
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.3 分组分析\分组分析.csv',
engine='python',encoding='utf8')
按照性别列进行分组,对年龄列进行均值统计
ga=data.groupby(
by=['gender']
)['age'].agg('mean')
取消分组列索引的设置
ga=data.groupby(
by=['gender'],as_index=False
)['age'].agg('mean')
5.4 结构分析
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.4 结构分析\结构分析.csv',
engine='python',encoding='utf8')
按照性别列进行分组,按照id列进行计数统计
ga=data.groupby(
by=['gender']
)['id'].agg('count')
计算总用户数
ga
计算总用户数
ga.sum()
计算不同性别用户比例
ga/ga.sum()
5.5分布分析
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.5 分布分析\分布分析.csv',
engine='python',encoding='utf8')
对年龄进行分组,统计各年龄用户数
aggresult=data.groupby(
by=['年龄']
)['用户ID'].agg('count')
设置年龄分组阈值
bins=[0,20,30,40,100]
设置年龄分段标签
ageLabels=['20岁及以下','21岁到30岁','31岁到40岁','40岁以上']
生成年龄分段列
import pandas
data['年龄分层']=pandas.cut(
data.年龄,
bins,
labels=ageLabels
)
使用年龄分层作为分组列,统计每个年龄分层用户数
aggresule=data.groupby(
by=['年龄分层']
)['用户ID'].agg('count')
对每个年龄分层的用户数求和
aggresule.sum()
计算各年龄分层用户比例
aggresule/aggresult.sum()
5.6交叉分析
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.6 交叉分析\交叉分析.csv',
engine='python',encoding='utf8')
设置年龄分组阈值
bins=[0,20,30,40,100]
设置年龄分段标签
ageLabels=['20岁及以下','21岁到30岁','31岁到40岁','40岁以上']
生成年龄分层列
data['年龄分层']=pandas.cut(
data.年龄,
bins,
labels=ageLabels)
进行交叉统计,行为年龄分层,列为性别,对用户ID进行计数统计
ptResult=data.pivot_table(
values='用户ID',
index='年龄分层',
columns='性别',
aggfunc='count'
)
5.7 RFM分析
步骤1:读入数据
步骤2:将交易日期设置为日期数据类型
步骤3:求交易日期到在的距离
步骤4:统计每个用户距离现在有多久没有消费,即找出最小最近的消费距离
步骤5:统计每个用户交易总次数,即对订单数计数
步骤6:统计每个用户交易总额,即对每次交易金融求和
步骤7:求R_S得分(该指标所有数据分为5等分,0、20%,40%,60%,80%,100%,并用5,4,3,2,1给每个观测值签上该指标对应5等分标签)
步骤8:求F_S得分(该指标所有数据分为5等分,0、20%,40%,60%,80%,100%,并用1,2,3,4,5给每个观测值签上该指标对应5等分标签)
步骤9:求M_S得分(该指标所有数据分为5等分,0、20%,40%,60%,80%,100%,并用1,2,3,4,5给每个观测值签上该指标对应5等分标签)
步骤10 计算RMF总得分(代入公式:RFM=100R_S.astype(int)+10F_S.astype(int)+1*F_S.astype(int))
步骤11:RMF总分进行分为8等分(该指标所有数据分为8等分,0、12.5%,25%,37.5%,50%,62.5%,75%,87.5%,100%并用1,2,3,4,5,6,7,8给每个观测值签上该指标对应8等分标签)
客户划分类别依据
R值 高 高 高 高 低 低 低 低
F值 高 高 低 低 高 高 低 低
M值 高 低 高 低 高 低 高 低
客户类型 高价值客户 一般价值客户 重点发展客户 一般发展客户 重点保持客户 一般保持客户 重点挽留客户 潜在客户
level 8 7 6 5 4 3 2 1
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.7 RFM分析\RFM分析.csv',
engine='python',encoding='utf8')
将交易日期设置为日期数据类型
data['DealDateTime']=pandas.to_datetime(
data.DealDateTime,
format='%Y/%m/%d')
求交易日期到在的距离
from datetime import datetime
data['DateDiff']=datetime.now()-data['DealDateTime']
从时间距离中获取天数
data['DateDiff']=data['DateDiff'].dt.days
统计每个用户距离现在有多久没有消费,即找出最小最近的消费距离
R_Agg=data.groupby(
by=['CustomerID'],
as_index=False
)['DateDiff'].agg(min)
统计每个用户交易总次数,即对订单数计数
F_Agg=data.groupby(
by=['CustomerID'],
as_index=False
)['OrderID'].agg('count')
统计每个用户交易总额,即对每次交易金融求和
M_Agg=data.groupby(
by=['CustomerID'],
as_index=False
)['Sales'].agg('sum')
把统计结果关联起来,整合为一个数据框
因为关联列名CUStomerID都一样,因此可以省略on条件
aggData=R_Agg.merge(F_Agg).merge(M_Agg)
修改列名
aggData.columns=['CustomerID','RecencyAgg','FrequencyAgg','MonetaryAgg']
根据用户最近消费距离,按照从小到大的顺序
bins=aggData.RecencyAgg.quantile(
q=[0,0.2,0.4,0.6,0.8,1],
interpolation='nearest'
)
cut函数分段区间默认左开放,右封闭,为了避免分段数值的最小值不在分段区间内
所以并bins参数列表最小值设置为0
bins[0]=0
用户越久没有消费,R分值越小,因此对应的得分需要从大到小排序
以标签值方式进行赋值
rLabels=[5,4,3,2,1]
根据百分位数对数据进行分段
import pandas
R_S=pandas.cut(
aggData.RecencyAgg,
bins,labels=rLabels
)
--F
根据用户消费频次,按照从小到顺序
求排在0%,20%,40%,60%,80%,100%
bins=aggData.FrequencyAgg.quantile(
q=[0,0.2,0.4,0.6,0.8,1],
interpolation='nearest'
)
cut函数分段区间默认左开放,右封闭,为了避免分段数值的最小值不在分段区间内
所以并bins参数列表最小值设置为0
bins[0]=0
用户越久没有消费,R分值越小,因此对应的得分需要从大到小排序
以标签值方式进行赋值
fLabels=[5,4,3,2,1]
根据百分位数对数据进行分段
import pandas
F_S=pandas.cut(
aggData.FrequencyAgg,
bins,labels=fLabels)
--M
根据用户消费频次,按照从小到顺序
求排在0%,20%,40%,60%,80%,100%
bins=aggData.MonetaryAgg.quantile(
q=[0,0.2,0.4,0.6,0.8,1],
interpolation='nearest'
)
cut函数分段区间默认左开放,右封闭,为了避免分段数值的最小值不在分段区间内
所以并bins参数列表最小值设置为0
bins[0]=0
用户越久没有消费,R分值越小,因此对应的得分需要从大到小排序
以标签值方式进行赋值
mLabels=[5,4,3,2,1]
根据百分位数对数据进行分段
import pandas
M_S=pandas.cut(
aggData.MonetaryAgg,
bins,labels=mLabels)
将R, F, M的值分别增加到aggData数据框中
aggData['R_S']=R_S
aggData['F_S']=F_S
aggData['M_S']=M_S
因为R_S、F_S、M_S得分值采用标签赋值方法获取
所以要先转换为数值型再计算出RFM得分值
aggData['RFM']=100R_S.astype(int)+10F_S.astype(int)+1*F_S.astype(int)
根据RFM这一列,按照从小到大顺序,分为8等分,因此,需要求出
排在0%,12.5%,25%,37.5%,50%,62.5%,75%,87.5%,100%的数据点
bins=aggData.RFM.quantile(
q=[0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1],
interpolation='nearest'
)
cut函数分段区间默认左开放,右封闭,为了避免分段数值的最小值不在分段区间内
所以并bins参数列表最小值设置为0
bins[0]=0
RFM值越大,得分越高,故对应得分从小到大排列,以标签方式赋值
rfmLabels=[1,2,3,4,5,6,7,8]
根据百分位数对数据进行分段
aggData['level']=pandas.cut(
aggData.RFM,
bins,
labels=rfmLabels
)
对level进行分组,按照客户ID进行计数统计
aggData.groupby(
by=['level']
)['CustomerID'].agg('count')
5.8 矩阵分析
import pandas as pd
data=pd.read_csv('D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\数据源\PDABook\第五章\5.8 矩阵分析\矩阵分析.csv',
engine='python',encoding='utf8')
按照省份分组,对月消费进行均值统计
costAgg=data.groupby(
by=['省份'],
as_index=False
)['月消费(元)'].agg('mean')
按照省份分组,对月流量进行均值统计
dataAgg=data.groupby(
by=['省份'],
as_index=False
)['月流量(MB)'].agg('mean')
把两个统计结果合并起来
aggData=costAgg.merge(dataAgg)
引入matplotlib
import matplotlib
import matplotlib.pyplot as plt
通过字体路径文字大小,生成字体属性,赋值给font变量,用于点的标签.这个文件要下载,通过路径读入
font=matplotlib.font_manager.FontProperties(
fname='D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\SourceHanSansCN-Light\SourceHanSansCN-Light.otf',size=10
)
生成字体属性,赋值给labelFont变量,用于坐标轴标签
labelFont=matplotlib.font_manager.FontProperties(
fname='D:\曾海峰\谁说菜鸟不会数据分析(Python篇)\SourceHanSansCN-Light\SourceHanSansCN-Light.otf',size=10
)
蓝色,作为点颜色
mainColor=(91/255,155/255,213/255,1)
灰色,作为点的颜色
fontColor=(110/255,110/255,110/255,1)
设置坐标轴的样式
新建一个绘图窗口
fig=plt.figure()
计算x轴和Y轴的范围,如何把范围定义为最大值与最小值之间
那么最小值和最大值这两个点,就会非常靠近图形边缘,不好看
所以需要留1%的空白边缘,即范围[最小值(1-1%),最大值[最小值(1+1%)]
把空白边缘设置为变量,方便后面调整这个值
gap=0.01
计算x轴范围值
xMin=aggData['月消费(元)'].min()(1-gap)
xMax=aggData['月消费(元)'].max()(1+gap)
计算y轴范围值
yMin=aggData['月流量(MB)'].min()(1-gap)
yMax=aggData['月流量(MB)'].max()(1+gap)
设置x轴,y轴坐标范围
plt.xlin=(xMin,xMax)
plt.ylin=(yMin,yMax)
设置x轴,y轴的坐标轴的刻度,本案例将所有的刻度去掉
plt.xticks([])
plt.yticks([])
3绘制散点图
plt.scatter(
aggData['月消费(元)'],
aggData['月流量(MB)'],
s=10,marker='o',color=mainColor
)
设置坐标轴的标签
plt.xlabel(
'人均月消费(元)',
color=fontColor,
fontproperties=labelFont
)
plt.ylabel(
'人均月流量(MB)',
color=fontColor,
fontproperties=labelFont
)
4绘制坐标轴分界线
plt.vlines(
x=data['月消费(元)'].mean(),
ymin=yMin,ymax=yMax,
linewidth=1,color=mainColor
)
plt.hlines(
y=data['月流量(MB)'].mean(),
xmin=xMin,xmax=xMax,
linewidth=1,color=mainColor
)
添加数据标签与象限编号
标注四个象限的标记,在不同的分辨率下,需要微调下位置
plt.text(
xMax - 0.5,yMax - 5,
'Ⅰ',color=fontColor,fontsize=10
)
plt.text(
xMin,yMax - 5,
'Ⅱ',color=fontColor,fontsize=10
)
plt.text(
xMin,yMin,
'Ⅲ',color=fontColor,fontsize=10
)
plt.text(
xMax - 0.6,yMin,
' Ⅳ',color=fontColor,fontsize=10
)
画标签,遍历数据每一行
然后根据列名获取到数据对应的x轴和y轴的位置以及要绘制的省份
for i,r in aggData.iterrows():
#为了让标签显示得更加直观,需要对标签的位置做一些微调
#在x轴的位置,往右移动0.25,在Y轴的位置,往下移动1
plt.text(
r['月消费(元)']+0.25,
r['月流量(MB)']-1,
r['省份'],
color=fontColor,
fontproperties=font
)