数据分析之Pandas

Posted Maverick_曲流觞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据分析之Pandas相关的知识,希望对你有一定的参考价值。

3.Pandas

文章目录

3.3 Pandas进阶

import pandas as pd
import numpy as np

3.3.1 数据重塑和轴向旋转

(1)层次化索引

层次化索引是pandas的一项重要功能,他能使我们再一个轴上拥有多个索引

Series的层次化索引
s=pd.Series(np.arange(1,10),index=[['a','a','a','b','b','c','c','d','d'],[1,2,3,1,2,3,1,2,3]])
s
a  1    1
   2    2
   3    3
b  1    4
   2    5
c  3    6
   1    7
d  2    8
   3    9
dtype: int32
s.index
MultiIndex([('a', 1),
            ('a', 2),
            ('a', 3),
            ('b', 1),
            ('b', 2),
            ('c', 3),
            ('c', 1),
            ('d', 2),
            ('d', 3)],
           )
s['a':'b']
a  1    1
   2    2
   3    3
b  1    4
   2    5
dtype: int32
s[:,1]
a    1
b    4
c    7
dtype: int32

通过unstack方法可以将Series变成一个DataFrame

s.unstack()
123
a1.02.03.0
b4.05.0NaN
c7.0NaN6.0
dNaN8.09.0
s.unstack().stack()
a  1    1.0
   2    2.0
   3    3.0
b  1    4.0
   2    5.0
c  1    7.0
   3    6.0
d  2    8.0
   3    9.0
dtype: float64
DataFrame的层次化索引

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

data=pd.DataFrame(np.arange(12).reshape(4,3))
data
012
0012
1345
2678
391011
data=pd.DataFrame(np.arange(12).reshape(4,3),index=[['a','a','b','b'],[1,2,1,2]])
data
012
a1012
2345
b1678
291011
data=pd.DataFrame(np.arange(12).reshape(4,3),index=[['a','a','b','b'],[1,2,1,2]],columns=[['A','A','B'],['Z','X','C']])
data

选取列

data['A']

设置名称

data.index.names=['row1','row2']
data

data.columns.names=['column1','column2']
data

行顺序调整

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

层次化——电影数据示列

数据导入

df=pd.read_excel('movie_data2.xlsx')
df.head()
Unnamed: 0名字投票人数类型产地上映时间时长年代评分首映地点
00肖申克的救赎692795剧情/犯罪美国1994-09-10 00:00:0014219949.6多伦多电影节
11控方证人42995剧情/悬疑/犯罪美国1957-12-17 00:00:0011619579.5美国
22美丽人生327855剧情/喜剧/爱情意大利1997-12-20 00:00:0011619979.5意大利
33阿甘正传580897剧情/爱情美国1994-06-23 00:00:0014219949.4洛杉矶首映
44霸王别姬478523剧情/爱情/同性中国大陆1993-01-01 00:00:0017119939.4香港
df.drop('Unnamed: 0',axis=1)
df.index
RangeIndex(start=0, stop=38166, step=1)

set_index:可以把列变成索引
reset_index:把索引变成列

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

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

每一个索引都是一个元组

df.index[0]
('美国', 1994)

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

df.loc['美国'].head()

| | 名字 | 投票人数 | 类型 | 上映时间 | 时长 | 评分 | 首映地点 |
| —: | —: | -----------: | -------: | -------------: | ------------------: | —: | —: | -----------: |
| 年代 | | | | | | | |
| 1994 | 肖申克的救赎 | 692795 | 剧情/犯罪 | 1994-09-10 00:00:00 | 142 | 9.6 | 多伦多电影节 |
| 1957 | 控方证人 | 42995 | 剧情/悬疑/犯罪 | 1957-12-17 00:00:00 | 116 | 9.5 | 美国 |
| 1994| 阿甘正传 | 580897 | 剧情/爱情 | 1994-06-23 00:00:00 | 142 | 9.4 | 洛杉矶首映 |
| 2012 | 泰坦尼克号 | 157074 | 剧情/爱情/灾难 | 2012-04-10 00:00:00 | 194 | 9.4 | 中国大陆 |
| 1993 | 辛德勒的名单 | 306904 | 剧情/历史/战争 | 1993-11-30 00:00:00 | 195 | 9.4 | 华盛顿首映 |

这样做最大的好处就是我们可以简化很多的筛选环节

索引交换 swaplevel

df=df.swaplevel('产地','年代')
df.head()

取消层次化索引

df=df.reset_index()
df.head()
年代产地Unnamed: 0名字投票人数类型上映时间时长评分首映地点
01994美国0肖申克的救赎692795剧情/犯罪1994-09-10 00:00:001429.6多伦多电影节
11957美国1控方证人42995剧情/悬疑/犯罪1957-12-17 00:00:001169.5美国
21997意大利2美丽人生327855剧情/喜剧/爱情1997-12-20 00:00:001169.5意大利
31994美国3阿甘正传580897剧情/爱情1994-06-23 00:00:001429.4洛杉矶首映
41993中国大陆4霸王别姬478523剧情/爱情/同性1993-01-01 00:00:001719.4香港
(2)数据旋转

行列转化

data=df[:5]
data
年代产地Unnamed: 0名字投票人数类型上映时间时长评分首映地点
01994美国0肖申克的救赎692795剧情/犯罪1994-09-10 00:00:001429.6多伦多电影节
11957美国1控方证人42995剧情/悬疑/犯罪1957-12-17 00:00:001169.5美国
21997意大利2美丽人生327855剧情/喜剧/爱情1997-12-20 00:00:001169.5意大利
31994美国3阿甘正传580897剧情/爱情1994-06-23 00:00:001429.4洛杉矶首映
41993中国大陆4霸王别姬478523剧情/爱情/同性1993-01-01 00:00:001719.4香港

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

data.T
01234
年代19941957199719941993
产地美国美国意大利美国中国大陆
Unnamed: 001234
名字肖申克的救赎控方证人美丽人生阿甘正传霸王别姬
投票人数69279542995327855580897478523
类型剧情/犯罪剧情/悬疑/犯罪剧情/喜剧/爱情剧情/爱情剧情/爱情/同性
上映时间1994-09-10 00:00:001957-12-17 00:00:001997-12-20 00:00:001994-06-23 00:00:001993-01-01 00:00:00
时长142116116142171
评分9.69.59.59.49.4
首映地点多伦多电影节美国意大利洛杉矶首映香港

dataframe也可以使用stack和unstack,转化为层次索引的Series

data.stack()
0  年代                           1994
   产地                             美国
   Unnamed: 0                      0
   名字                         肖申克的救赎
   投票人数                       692795
   类型                          剧情/犯罪
   上映时间          1994-09-10 00:00:00
   时长                            142
   评分                            9.6
   首映地点                       多伦多电影节
1  年代                           1957
   产地                             美国
   Unnamed: 0                      1
   名字                           控方证人
   投票人数                        42995
   类型                       剧情/悬疑/犯罪
   上映时间          1957-12-17 00:00:00
   时长                            116
   评分                            9.5
   首映地点                           美国
2  年代                           1997
   产地                            意大利
   Unnamed: 0                      2
   名字                          美丽人生 
   投票人数                       327855
   类型                       剧情/喜剧/爱情
   上映时间          1997-12-20 00:00:00
   时长                            116
   评分                            9.5
   首映地点                          意大利
3  年代                           1994
   产地                             美国
   Unnamed: 0                      3
   名字                           阿甘正传
   投票人数                       580897
   类型                          剧情/爱情
   上映时间          1994-06-23 00:00:00
   时长                            142
   评分                            9.4
   首映地点                        洛杉矶首映
4  年代                           1993
   产地                           中国大陆
   Unnamed: 0                      4
   名字                           霸王别姬
   投票人数                       478523
   类型                       剧情/爱情/同性
   上映时间          1993-01-01 00:00:00
   时长                            171
   评分                            9.4
   首映地点                           香港
dtype: object
data.stack().unstack()
年代产地Unnamed: 0名字投票人数类型上映时间时长评分首映地点
01994美国0肖申克的救赎692795剧情/犯罪1994-09-101429.6多伦多电影节
11957美国1控方证人42995剧情/悬疑/犯罪1957-12-171169.5美国
21997意大利2美丽人生327855剧情/喜剧/爱情1997-12-201169.5意大利
31994美国3阿甘正传580897剧情/爱情1994-06-231429.4洛杉矶首映
41993中国大陆4霸王别姬478523剧情/爱情/同性1993-01-011719.4香港

3.3.2 数据分组、分组运算

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

按照电影产地进行分组

先定义一个分组变量group

group=df.groupby(df['产地'])
group
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002238D9028B0>

可以计算分组后的各个统计量

group.mean().head()
年代Unnamed: 0投票人数时长评分
产地
中国台湾1999.00970919350.5906158474.86407887.2572827.066667
中国大陆2004.59968420391.79142610898.29379381.4329306.064703
中国香港1991.10031619230.1171528167.44615988.5412146.474114
丹麦1999.09090920415.6111111993.85858688.1010107.245960
俄罗斯1992.53412920061.7534792098.81378493.2809817.310736

计算每年的平均评分

df['评分'].groupby(df['年代']).mean().head()
年代
1888    7.950000
1890    4.800000
1892    7.500000
1894    6.633333
1895    7.575000
Name: 评分, dtype: float64

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

df['年代']=df['年代'].astype('str')
df.groupby(df['产地']).mean().head()
Unnamed: 0投票人数时长评分
产地
中国台湾19350.5906158474.86407887.2572827.066667
中国大陆20391.79142610898.29379381.4329306.064703
中国香港19230.1171528167.44615988.5412146.474114
丹麦20415.6111111993.85858688.1010107.245960
俄罗斯20061.7534792098.81378493.2809817.310736

我们也可以传入多个分组变量

df.groupby([df['产地'],df['年代']]).mean().head()
Unnamed: 0投票人数时长评分
产地年代
中国台湾196314805.0121.000000113.06.4
196530282.0153.666667105.06.8
196626305.051.00000060.07.9
196716605.04444.000000112.08.0
196821282.589.00000083.07.4

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

df['评分'].groupby([df['产地'],df['年代']]).mean()
产地    年代  
中国台湾  1963    6.400000
      1965    6.800000
      1966    7.900000
      1967    8.000000
      1968    7.400000
                ...   
韩国    2012    6.064151
      2013    6.098198
      2014    5.650833
      2015    5.423853
      2016    5.730000
Name: 评分, Length: 1511, dtype: float64

Series通过unstack方法转化为dataframe——会产生缺失值

df['评分'].groupby([df['产地'],df['年代']]).mean().unstack().head()
年代18881890189218941895189618971898189919002008200920102011201220132014201520162017
产地
中国台湾NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN7.4200007.1000007.0538467.2318186.5560987.0764716.5222226.576000NaNNaN
中国大陆NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN6.5897266.5366286.3578315.8246065.7271875.3166674.9637574.9691894.712000NaN
中国香港NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN6.4767866.4425536.2454555.9710536.1105266.1057145.6166675.5891895.390909NaN
丹麦NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN7.0500007.1181827.3625007.0166677.4187506.5555567.1200007.1666677.000000NaN
俄罗斯NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN7.0244686.9227276.9743247.0060006.7841276.8905666.9659577.089655NaNNaN

5 rows × 127 columns

3.3.3 离散化处理

再实际的数据分析项目中,对有的数据属性,我们往往并不关注数据的绝对取值,只关注它所处的区间或等级。
比如我们可以把评分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:是否要用标记替换分组
retbins:返回x中对应的bins的列表
precision:精度

df['评分等级']=pd.cut(df['评分'],[0,3,5,7,9,10],labels=['E','D','C','B','A'])
df
年代产地Unnamed: 0名字投票人数类型上映时间时长评分首映地点评分等级
01994美国0肖申克的救赎692795剧情/犯罪1994-09-10 00:00:001429.600000多伦多电影节A
11957美国1控方证人42995剧情/悬疑/犯罪1957-12-17 00:00:001169.500000美国A
21997意大利2美丽人生327855剧情/喜剧/爱情1997-12-20 00:00:001169.500000意大利A
31994美国3阿甘正传580897剧情/爱情1994-06-23 00:00:001429.400000洛杉矶首映A
41993中国大陆4霸王别姬478523剧情/爱情/同性1993-01-01 00:00:001719.400000香港A
387251935美国387281935年57喜剧/歌舞1935-03-15 00:00:00987.600000美国B
387261986中国大陆38729血溅画屏95剧情/悬疑/犯罪/武侠/古装1905-06-08 00:00:00917.100000美国B
387271986中国大陆38730魔窟中的幻想51惊悚/恐怖/儿童1905-06-08 00:00:00788.000000美国B
387281977俄罗斯38731列宁格勒围困之星火战役 Блокада: Фильм 2: Ленинградский ме…32剧情/战争1905-05-30 00:00:00976.600000美国C
387292017美国38732复仇者联盟3123456剧情/科幻2017-05-04 00:00:001426.935704美国C

38730 rows × 11 columns

根据投票人数来刻画电影的热门
投票人数越多,热门程度越高

使用 np.percentile 进行分位数计算

bins=np.percentile(df['投票人数'],[0,20,40,60,80,100])
df['热门程度']=pd.cut(df['投票人数'],bins,labels=['E','D','C','B','A'])
df
年代产地Unnamed: 0名字投票人数类型上映时间时长评分首映地点评分等级热门程度
01994美国0肖申克的救赎692795剧情/犯罪1994-09-10 00:00:001429.600000多伦多电影节AA
11957美国1控方证人42995剧情/悬疑/犯罪1957-12-17 00:00:001169.500000美国AA
21997意大利2美丽人生327855剧情/喜剧/爱情1997-12-20 00:00:001169.500000意大利AA
31994美国3阿甘正传580897剧情/爱情1994-06-23 00:00:001429.400000洛杉矶首映AA
41993中国大陆4霸王别姬478523剧情/爱情/同性1993-01-01 00:00:001719.400000香港AA
387251935美国387281935年57喜剧/歌舞1935-03-15 00:00:00987.600000美国BE
387261986中国大陆38729血溅画屏95剧情/悬疑/犯罪/武侠/古装1905-06-08 00:00:00917.100000美国BD
387271986中国大陆38730魔窟中的幻想51惊悚/恐怖/儿童1905-06-08 00:00:00788.000000美国BE
387281977俄罗斯38731列宁格勒围困之星火战役 Блокада: Фильм 2: Ленинградский ме…32剧情/战争1905-05-30 00:00:00976.600000美国CE
387292017美国38732复仇者联盟3123456剧情/科幻2017-05-04 00:00:001426.935704美国CA

38730 rows × 12 columns

查看烂片:投票人数多,评分低

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

以上是关于数据分析之Pandas的主要内容,如果未能解决你的问题,请参考以下文章

PandasPandas处理Csv和Excel数据详解

pandaspandas中的常见函数

PandasPandas Daframe 常用用法

PandasPandas Daframe 常用用法

jupyter入门之pandas

pandaspandas.to_datatime()---时间格式转换

(c)2006-2024 SYSTEM All Rights Reserved IT常识

年代产地Unnamed: 0名字投票人数类型上映时间时长评分首映地点评分等级热门程度
6552011中国大陆655B区5187剧情/惊悚/恐怖2011-06-03 00:00:00892.3中国大陆EA
43762014中国大陆4376怖偶4867悬疑/惊悚2014-05-07 00:00:00882.8中国大陆EA
54132011中国大陆5413床下有人4309悬疑/惊悚2011-10-14 00:00:001002.8中国大陆EA
68022013中国大陆6802帝国秘符4351动作/冒险2013-09-18 00:00:00933.0中国大陆EA
82322011中国大陆8232飞天4764剧情2011-07-01 00:00:001152.9中国大陆EA
84062014中国大陆