Python 数据分析 —— Pandas ③

文章目录

  • 前提准备
  • 数据重塑(层次化索引)和轴向旋转(数据旋转)
    • 层次化索引
      • Series的层次化索引
      • DataFrame的层次化索引
      • 列与索引之间的转换
    • 数据旋转
  • 数据分组和分组运算
  • 数据离散化
  • 合并数据集
    • (1)append
    • (2)merge ⭐
    • (3)concat
  • 作业

  
  
  
  

前提准备

  

先导包

import numpy as np
import pandas as pd

再读数据

df = pd.read_excel(r'D:\数据分析\movie_data2.xlsx')

这样才能正式开始学习

  
  
  
  

数据重塑(层次化索引)和轴向旋转(数据旋转)

  

  

层次化索引

  
一个轴上拥有多个索引,使⾼维数据可以被紧凑的表示在我们熟悉的⼀维Series和⼆维DataFrame对象中,即降低维度形式处理高维度数据。

  

Series的层次化索引

  
多重索引通过 index 参数实现:

s = pd.Series(np.arange(1,10),index = [['a','a','a','b','b','c','c','d','d'],[1,2,3,1,2,1,2,1,2]])

Python 数据分析 —— Pandas ③_第1张图片

查看索引:

s.index

Python 数据分析 —— Pandas ③_第2张图片

MultiIndex 意思是:多索引

  

切片:

s.b
# 或
s['b']

在这里插入图片描述
  

s['a':'c']

Python 数据分析 —— Pandas ③_第3张图片

  

取内层:
  
逗号(,)前是外层,逗号(,)后是内层
  

取所有外层的 索引为1内层:

s[:,1]

Python 数据分析 —— Pandas ③_第4张图片

取(c,2)元素:

s['c',2]

在这里插入图片描述

  

通过 unstack(不堆叠)方法可以将Series变成一个DataFrame
Python 数据分析 —— Pandas ③_第5张图片

s.unstack()

Python 数据分析 —— Pandas ③_第6张图片

外层为行,内层为列

  

DataFrame的层次化索引

  
对于DataFrame,行和列都能够进行层次化索引。
  

先构造一个默认索引的DataFrame:

data = pd.DataFrame(np.arange(1,13).reshape(4,3))    # np.arange生成数据,reshape重构结构

Python 数据分析 —— Pandas ③_第7张图片

默认索引都从0开始

  

进行层次化索引

data = pd.DataFrame(np.arange(1,13).reshape(4,3),index = [['a','a','b','b'],[1,2,1,2]])

Python 数据分析 —— Pandas ③_第8张图片

  

也进行层次化索引

data = pd.DataFrame(np.arange(1,13).reshape(4,3),index = [['a','a','b','b'],[1,2,1,2]],columns = [['A','A','B'],['X','Y','Z']])

Python 数据分析 —— Pandas ③_第9张图片

  

选取列:

参数只能是A或B

data['A']

Python 数据分析 —— Pandas ③_第10张图片

  

设置行或列的名称:

  • index.names
  • columns.names

  

data.index.names = ['row1','row2']
data.columns.names = ['col1','col2']

Python 数据分析 —— Pandas ③_第11张图片

  

调整 索引 顺序:

  • swaplevel :交换内、外层索引

  
调整row1,row2的顺序

data.swaplevel('row1','row2')

Python 数据分析 —— Pandas ③_第12张图片

  

列与索引之间的转换

  

  • set_index 可以把列变成索引
  • reset_index 是把索引变成列

  

了解了层次化索引的基本知识以后,将电影数据也处理成一种多层索引的结构。

df.index

在这里插入图片描述
这是原始的单层索引

  
  
把产地和年代同时设成索引,产地是外层索引,年代为内层索引

  
set_index

df = df.set_index(['产地','年代'])    # 外层写前面,内层写后面

顺序很重要!外层写前面,内层写后面。

Python 数据分析 —— Pandas ③_第13张图片

  

每个索引都是一个元组

df.index[4]

在这里插入图片描述

  

获取所有的美国电影。由于产地信息已经变成了索引,因此要用 .loc 方法

df.loc['美国',:]

# 或省略后面参数

df.loc['美国']

Python 数据分析 —— Pandas ③_第14张图片

loc 的使用在:通过标签选择数据 —— loc

  
  

取消层次化索引,把索引变回列

  
reset_index

df = df.reset_index(['产地','年代'])

# 或

# 如果是全部取消,就可以省略参数
df = df.reset_index()

Python 数据分析 —— Pandas ③_第15张图片

  

  

数据旋转

  

拿前5部电影为例

data = df.head()

Python 数据分析 —— Pandas ③_第16张图片

  

.T 可以直接让数据的行列进行交换

data.T

Python 数据分析 —— Pandas ③_第17张图片

  

DataFrame可以使用stack,转化为层次化索引的Series
  

data = data.stack()

Python 数据分析 —— Pandas ③_第18张图片
Python 数据分析 —— Pandas ③_第19张图片

此时数据为层次化的 Series

  

层次化索引的Series可以使用unstack,转化为DataFrame
  

data = data.unstack()

Python 数据分析 —— Pandas ③_第20张图片

没有数据时,会产生缺失值 NaN。

  
  
  
  

数据分组和分组运算

  

  
groupby :能实现数据的分组和分组运算,作用类似于数据透视表

Python 数据分析 —— Pandas ③_第21张图片

把相同键进行分组,再把每组的值进行运算。

  
  

先定义一个分组变量 group,按照电影的产地进行分组
  

group = df.groupby(df['产地'])

在这里插入图片描述

此时group是DataFrame下GroupBy的对象

  
  

计算分组后的各个统计量
  

# 均值
group.mean()

Python 数据分析 —— Pandas ③_第22张图片
Python 数据分析 —— Pandas ③_第23张图片

  

# 求和
group.sum()

Python 数据分析 —— Pandas ③_第24张图片
Python 数据分析 —— Pandas ③_第25张图片

  
  

计算每年的平均评分
  

df['评分'].groupby(df['年代']).mean()

Python 数据分析 —— Pandas ③_第26张图片

  
  

只会对数值变量进行分组计算
  

求平均时不想带上年代,就把年代转为字符串类型就行

df.年代 = df.年代.astype('str')

这时再分组,就不会对年代求平均了

df.groupby(df.产地).mean()

Python 数据分析 —— Pandas ③_第27张图片
Python 数据分析 —— Pandas ③_第28张图片

  
  

传入多个分组变量
  

df.groupby([df.产地,df.年代]).mean()

Python 数据分析 —— Pandas ③_第29张图片

  
  

获得每个地区,每一年的电影的评分的均值
  

df.groupby([df.产地,df.年代])['评分'].mean()

# 或

df['评分'].groupby([df.产地,df.年代]).mean()

Python 数据分析 —— Pandas ③_第30张图片

  
  
  
  

数据离散化

  

  
在实际的数据分析项目中,对有的数据属性,我们往往并不关注数据的绝对取值,只关注它所处的区间或者等级。即,我们往往取得是一个区间的数据,而非简单一个值的数据。

比如,我们可以把评分9分及以上的电影定义为A,7到9分定义为B,5到7分定义为C,3到5分定义为D,小于3分定义为E。
  

离散化也可称为分组、区间化

  

Pandas提供了方便的函数 cut()

pd.cut(x, bins, right = True, labels = None, retbins = False, precision = 3, include_lowest = False)

  
参数:

  • x :需要离散化的数组,Series、DataFrame对象
  • bins :分组的依据
  • right :是否包含右端点,默认为True
  • include_lowest :是否包含左端点,默认为False
  • labels :是否用标记替换返回出来的分组bins

后面这俩不常用

  • retbins :返回x中每个值对应的bins列表
  • precision :精度

  

评分9分及以上的电影定义为A,7到9分定义为B,5到7分定义为C,3到5分定义为D,小于3分定义为E

如果不定义labels:

pd.cut(df['评分'],[0,3,5,7,9,10])

Python 数据分析 —— Pandas ③_第31张图片

每个区间都是默认的左开右闭
  
定义labels:

pd.cut(df['评分'],[0,3,5,7,9,10],labels = ['E','D','C','B','A'])

Python 数据分析 —— Pandas ③_第32张图片
  

把评分等级这列加在数据集中:

df['评分等级'] = pd.cut(df['评分'],[0,3,5,7,9,10],labels = ['E','D','C','B','A'])

Python 数据分析 —— Pandas ③_第33张图片

  

根据投票人数划分电影的热门程度。投票人数越多,热门程度越高

  
1.先弄出来bins,有个分组依据。否则哪什么划分程度呀

bins = np.percentile(df['投票人数'],[0,20,40,60,80,100])

  
np.percentile 参数:

  • a :数组array,用来算分位数的对象,可以是多维的数组
  • q :介于0-100的 float 数,用来计算是几分位的参数

  
2.写 cut

df['热门程度'] = pd.cut(df['投票人数'],bins,labels = ['差劲','不太行','一般般','比较热','大热门'])

Python 数据分析 —— Pandas ③_第34张图片

  

大烂片合集:投票人数很多,评分很低

df[(df.热门程度 == '大热门') & (df.评分等级 == 'E')]

Python 数据分析 —— Pandas ③_第35张图片
Python 数据分析 —— Pandas ③_第36张图片

妈耶!几乎全是中国电影

  

冷门高分电影

df[(df.热门程度 == '差劲') & (df.评分等级 == 'A')]

Python 数据分析 —— Pandas ③_第37张图片

  

将处理后的数据进行保存

df.to_excel(r'D:\数据分析\movie_data3.xlsx')

  
  
  
  

合并数据集

  

  

(1)append

  

把产地为中国和产地为美国的电影数据从数据集中拆分出来,再合并
  
先把数据集拆分为多个

df_usa = df[df.产地 == '美国']
df_china = df[df.产地 == '中国大陆']

将这两个数据集进行合并

df_china.append(df_usa)

Python 数据分析 —— Pandas ③_第38张图片

  

  

(2)merge ⭐

  
merge 用来合并Series或DataFrame。
只能用于两个表的拼接,且连接方向是左右拼接,一个左表一个右表。
  

pd.merge(left, right, how = 'inner', on = None, left_on = None, right_on = None, left_index = False, right_index = False, sort = True, suffixes = ('_x', '_y'), copy = True, indicator = False)

  
参数:

  • left :对象 —— 左边待拼接的数据文件
  • right :另一个对象 —— 右边待拼接的数据文件
  • how :通过什么方式连接数据。有 left 返回的结果只包含左列、right 返回的结果只包含右列、outer 并集、inner 交集几个值,默认为inner。
  • on :以什么字段进行拼接(哪个字段作为主键(连接键)),该字段必须在左右数据中都存在。如果两个表里没有完全一致的列名,但是有信息一致的列,就需要用 left_on 和 right_on 共同来指定。
  • left_on :左表的连接键字段
  • right_on :右表的连接键字段
  • left_index :如果为True,则将左表的索引作为连接键。默认为False
  • right_index :如果为True,则将右表的索引作为连接键。默认为False
  • sort :通过连接键,按字典顺序对结果进行排序。
  • suffixes :如果左右数据出现重复列,新数据表头会用此后缀进行区分,默认为 _x 和 _y
  • copy :始终从传递的DataFrame对象复制数据(默认为True),即使不需要重建索引也是如此。
  • indicator :显示拼接后的表中数据来自于哪一个表格。表的最后会有一个新列 _merge,显示这一条记录来自于左右哪个表,left_only或right_only。如果两表都有数据会标记both,默认为False。

  

练习:
  
选取6部热门电影:

df1 = df.loc[:5]

Python 数据分析 —— Pandas ③_第39张图片
  

df2 = df.loc[:5][['名字','产地']]
df2['票房'] = [16543,6498,68786,4897664,79784,35767]

Python 数据分析 —— Pandas ③_第40张图片
  
打乱 df2 数据:

df2 = df2.sample(frac = 1)

Python 数据分析 —— Pandas ③_第41张图片

  
重新给 df2 赋索引 :

df2.index = range(len(df2))

Python 数据分析 —— Pandas ③_第42张图片
  
上面这一通操作,只打乱了数据,而没打乱索引。

  

把 df1 和 df2 合并:

我们发现,df2有票房数据,df1有评分等其他信息。
由于样本的index索引顺序不一致,因此不能采用直接复制的方法。

根据电影名字合并(电影名字作主键)

pd.merge(df1,df2,how = 'inner',on = '名字')

在这里插入图片描述

因为 df1 和 df2 中都有产地,所以列名后面自动加了 _x 和 _y

  

  

(3)concat

  
将多个数据集进行批量合并

  

先弄三个数据集:

df1 = df[:10]
df2 = df[100:110]
df3 = df[200:210]

  
再合并:

dff = pd.concat([df1,df2,df3])

Python 数据分析 —— Pandas ③_第43张图片
Python 数据分析 —— Pandas ③_第44张图片
在这里插入图片描述

  
  
  
  

作业

  

  
(1)读取数据。读取之前作业保存的 “酒店数据1.xlsx”

df = pd.read_excel(r'D:\数据分析\酒店数据.xlsx')

Python 数据分析 —— Pandas ③_第45张图片

  

(2)将“类型”和“名字”设置为层次化索引,并交换索引的位置。然后将层次化索引取消。

# 层次化索引
df = df.set_index(['类型','名字'])

Python 数据分析 —— Pandas ③_第46张图片

  

# 交换索引位置
df.swaplevel('类型','名字')

Python 数据分析 —— Pandas ③_第47张图片

  

# 取消层次化索引
df = df.reset_index()

Python 数据分析 —— Pandas ③_第48张图片

  

(3)将数据集转置,获取转置后的index和columns。

# 转置
data = df.T

Python 数据分析 —— Pandas ③_第49张图片
  

data.index

在这里插入图片描述

  

data.columns

在这里插入图片描述

  

(4)用groupby方法计算每个地区的评分人数的总和以及均值

group = df['评分人数'].groupby(df['地区'])
group.sum()
group.mean()

Python 数据分析 —— Pandas ③_第50张图片

Python 数据分析 —— Pandas ③_第51张图片

  

(5)用groupby方法计算每个类型的平均价格,,最高价和最低价

group = df['价格'].groupby(df['类型']).mean()
group.max()
group.min()

Python 数据分析 —— Pandas ③_第52张图片

  

(6)数据离散化,按照价格将酒店分为3个等级,0-500为C,500-1000为B,大于1000为A,列名设置为“价格等级”

df['价格等级'] = pd.cut(df['价格'],[0,500,1000,1000000],labels = ['C','B','A'])

Python 数据分析 —— Pandas ③_第53张图片

  

(7)获取评分均值最高和最低的地区的数据,分别使用append和concat方法将获取的两个数据集合并

group = df['评分'].groupby(df['地区']).mean()
group.sort_values()

Python 数据分析 —— Pandas ③_第54张图片

默认升序排列,最下面的“屯门”评分均值最高,最上面的“葵青”评分均值最低。

df1 = df[df.地区 == '屯门']
df2 = df[df.地区 == '葵青']

Python 数据分析 —— Pandas ③_第55张图片
Python 数据分析 —— Pandas ③_第56张图片
  

df1.append(df2)

Python 数据分析 —— Pandas ③_第57张图片

  

pd.concat([df1,df2])

Python 数据分析 —— Pandas ③_第58张图片

  

(8)数据离散化,按照评分人数将酒店平均分为3个等级,三个等级的酒店数量尽量保持一致。评分人数最多的为A,最少的为C。列名设置为“热门等级”

bins = np.percentile(df['评分人数'],[0,33,66,100])
df['热门等级'] = pd.cut(df['评分人数'],bins,labels = ['C','B','A'])

Python 数据分析 —— Pandas ③_第59张图片

  

(9)选出热门等级为A,价格等级也为A的酒店数据,计算其平均评分

temp1 = df.loc[(df.热门等级 == 'A') & (df.价格等级 == 'A')]
temp1['评分'].mean()

  

(10)取价格最高的5个酒店数据,使用stack和unstack方法实现DataFrame和Series之间的转换

data = df.sort_values('价格',ascending = False)[:5]

Python 数据分析 —— Pandas ③_第60张图片

  

data = data.stack()

Python 数据分析 —— Pandas ③_第61张图片
Python 数据分析 —— Pandas ③_第62张图片

  

data = data.unstack()

Python 数据分析 —— Pandas ③_第63张图片

  

(11)纵向拆分数据集,分为df1和df2,df1包含类型,名字,城市,地区;df2包含名字,地点,评分,评分人数,价格,价格等级,热门等级

df1 = df.loc[:][['类型','名字','城市','地区']]

Python 数据分析 —— Pandas ③_第64张图片

  

df2 = df.loc[:][['名字','地点','评分','评分人数','价格','价格等级','热门等级']]

Python 数据分析 —— Pandas ③_第65张图片

  

(12)将df2按照价格进行排序,重新设置df2的索引。索引值等于价格排名(从1开始依次加一)。

df2 = df2.sort_values('价格')

Python 数据分析 —— Pandas ③_第66张图片

此时索引index很乱,需重新设置

df2.index = range(len(df2))

Python 数据分析 —— Pandas ③_第67张图片

  

(13)使用merge方法将df1和df2合并。

df = pd.merge(df1,df2,on = '名字')

Python 数据分析 —— Pandas ③_第68张图片

  

(14)将合并后的数据集保存数据到“酒店数据2.xlsx”。

df.to_excel(r'D:\数据分析\酒店数据2.xlsx')

你可能感兴趣的:(Python数据分析,python,数据分析,数据挖掘)