2725266

(23) 2024-08-31 20:01:01

Pandas 数据分析入门

学习目标

  • 掌握在Pandas中计算常用统计量的方法
  • 初步使用pandas进行简单排序、分组、聚合等计算

1 计算常用统计值

  • 加载数据之后,可以通过之前学习的内容计算最大值,最小值,平均值,分位数,方差等方式对数据的分布情况做基本了解,这里就不再重复讲解
import pandas as pd college = pd.read_csv('data/college.csv') college.head() # 输出结果如下 
INSTNM CITY STABBR HBCU MENONLY WOMENONLY RELAFFIL SATVRMID SATMTMID DISTANCEONLY UGDS_2MOR UGDS_NRA UGDS_UNKN PPTUG_EF CURROPER PCTPELL PCTFLOAN UG25ABV MD_EARN_WNE_P10 GRAD_DEBT_MDN_SUPP
0 Alabama A & M University Normal AL 1.0 0.0 0.0 0 424.0 420.0 0.0 0.0000 0.0059 0.0138 0.0656 1 0.7356 0.8284 0.1049 30300 33888
1 University of Alabama at Birmingham Birmingham AL 0.0 0.0 0.0 0 570.0 565.0 0.0 0.0368 0.0179 0.0100 0.2607 1 0.3460 0.5214 0.2422 39700 21941.5
2 Amridge University Montgomery AL 0.0 0.0 0.0 1 NaN NaN 1.0 0.0000 0.0000 0.2715 0.4536 1 0.6801 0.7795 0.8540 40100 23370
3 University of Alabama in Huntsville Huntsville AL 0.0 0.0 0.0 0 595.0 590.0 0.0 0.0172 0.0332 0.0350 0.2146 1 0.3072 0.4596 0.2640 45500 24097
4 Alabama State University Montgomery AL 1.0 0.0 0.0 0 425.0 430.0 0.0 0.0098 0.0243 0.0137 0.0892 1 0.7347 0.7554 0.1270 26600 33118.5

5 rows × 27 columns

  • 数据集字段说明,大家课后可以自行探索该数据集背后的内容
列名 字段含义
INSTNM 大学名称
CITY 所在城市
STABBR 所在州简称
HBCU 历史上的黑人学员和大学
MENONLY 0/1 只有男学生
WOMENONLY 0/1 只有女学生
RELAFFIL 0/1 宗教信仰
SATVRMID SAT考试 Verbal分数中位数
SATMTMID SAT考试 数学分数中位数
DISTANCEONLY 只接受远程教育学生
UGDS 本科招生
UGDS_WHITE 本科生白人比例
UGDS_BLACK 本科生黑人比例
UGDS_HISP 本科生拉丁裔比例
UGDS_ASIAN 本科生亚裔比例
UGDS_AIAN 本科生美洲印第安人/阿拉斯加土著比例
UGDS_NHPI 本科生夏威夷/太平洋群岛土著比例
UGDS_2MOR 本科生混血比例
UGDS_NRA 本科生中留学生比例
UGDS_UNKN 本科生未知族裔比例
PPTUG_EF 非全日制学生比例
CURROPER 0/1 正在运营
PCTPELL 佩尔资助计划学生比例
PCTFLOAN 学费贷款学生比例
UG25ABV 年龄大于25岁的学生比例
MD_EARN_WNE_P10 入学10年后收入中位数
GRAD_DEBT_MDN_SUPP 毕业生债务中位数
  • 查看数据行列数
college.shape # 输出结果如下 (7535, 27) 
  • 【重要】以数据统计信息为例,做行列转换
college.describe() # 单独运行并查看 college.describe().T # 单独运行并查看 # 单独运行结果如下图所示 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bimg3P6U-35)(./img/df行列转换.png)]

  • 非数值数据的统计信息
  • 在04章节中 2.2.4 describe函数 小节中,我们用describe函数对数据集中的某一列数据做基本统计,在刚才我们发现:df.describe()返回的仅是所有数值列的统计信息
  • 列值是数值类型的统计返回和非数值类型的统计返回结果不一样
  • 那么在对整个数据集做基本统计时,也是使用describe函数
  • 默认的返回结果,是对所有数值类型的列做基础统计
  • 如果想返回非数值类型的所有列的基本统计结果,在使用describe函数时,需要使用特定参数
# 固定用法 import numpy as np college.describe(include=[np.object, pd.Categorical]) # 单独运行并查看 college.describe(include=[np.object, pd.Categorical]).T # 单独运行并查看 # 单独运行结果如下图所示 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oB9w4ApF-37)(./img/非数值列的统计信息.png)]

  • df.info()方法返回所有字段的条目数量、数据类型、是否缺失,及当前数据集整体的内存占用情况
college.info() # 输出结果如下 <class 'pandas.core.frame.DataFrame'> RangeIndex: 7535 entries, 0 to 7534 Data columns (total 27 columns): INSTNM 7535 non-null object CITY 7535 non-null object STABBR 7535 non-null object HBCU 7164 non-null float64 MENONLY 7164 non-null float64 WOMENONLY 7164 non-null float64 RELAFFIL 7535 non-null int64 SATVRMID 1185 non-null float64 SATMTMID 1196 non-null float64 DISTANCEONLY 7164 non-null float64 UGDS 6874 non-null float64 UGDS_WHITE 6874 non-null float64 UGDS_BLACK 6874 non-null float64 UGDS_HISP 6874 non-null float64 UGDS_ASIAN 6874 non-null float64 UGDS_AIAN 6874 non-null float64 UGDS_NHPI 6874 non-null float64 UGDS_2MOR 6874 non-null float64 UGDS_NRA 6874 non-null float64 UGDS_UNKN 6874 non-null float64 PPTUG_EF 6853 non-null float64 CURROPER 7535 non-null int64 PCTPELL 6849 non-null float64 PCTFLOAN 6849 non-null float64 UG25ABV 6718 non-null float64 MD_EARN_WNE_P10 6413 non-null object GRAD_DEBT_MDN_SUPP 7503 non-null object dtypes: float64(20), int64(2), object(5) memory usage: 1.6+ MB 

2 常用排序方法

2.1 从最大的N个值中选取最小值

找到小成本高口碑的5部电影,思路:

  • 输出和需求相关的列,观察数据
  • 选出口碑评分(imdb_score字段)最高的电影
  • 上一步的结果中,挑出预算最小的五部
  • 指定分析需求相关字段,输出新的df
movie = pd.read_csv('data/movie.csv') # 仅显示 电影名字 imdb评分 花费预算 movie2 = movie[['movie_title', 'imdb_score', 'budget']] movie2.head() 

输出结果

movie_title imdb_score budget
0 Avatar 7.9 .0
1 Pirates of the Caribbean: At World’s End 7.1 .0
2 Spectre 6.8 .0
3 The Dark Knight Rises 8.5 .0
4 Star Wars: Episode VII - The Force Awakens 7.1 NaN
  • 用nlargest方法,选出imdb_score分数最高的100个
# df.nlargest(n, '列名') # 根据指定列的值由大到小排列,返回n行数据 movie2.nlargest(100, 'imdb_score').head() 

输出结果

movie_title imdb_score budget
2725 Towering Inferno 9.5 NaN
1920 The Shawshank Redemption 9.3 .0
3402 The Godfather 9.2 .0
2779 Dekalog 9.1 NaN
4312 Kickboxer: Vengeance 9.1 .0
  • 使用nsmallest方法再从中挑出预算最小的五部
# df.nsmallest(n, '列名') # 根据指定列的值由小到大排列,返回n行数据 movie2.nlargest(100, 'imdb_score').nsmallest(5, 'budget') 

输出结果

movie_title imdb_score budget
4804 Butterfly Girl 8.7 .0
4801 Children of Heaven 8.5 .0
4706 12 Angry Men 8.9 .0
4550 A Separation 8.4 .0
4636 The Other Dream Team 8.4 .0

2.2 通过排序选取每组的最大值

找到每年imdb评分最高的电影,思路:

  • 年份由大到小排序,观察数据,找规律
  • 按年份、评分,由大到小排序,观察数据(分组)
  • 上述结果按照年份去重、仅保留第一个(去重)
  • sort_values 按照年份排序,ascending 升序排列
# df.sort_values('列名', ascending=False) # 指定字段由大到小降序排列 movie2 = movie[['movie_title', 'title_year', 'imdb_score']] movie2.sort_values('title_year', ascending=False).head() 

输出结果

movie_title title_year imdb_score
3884 The Veil 2016.0 4.7
2375 My Big Fat Greek Wedding 2 2016.0 6.1
2794 Miracles from Heaven 2016.0 6.8
92 Independence Day: Resurgence 2016.0 5.5
153 Kung Fu Panda 3 2016.0 7.2
  • 同时对title_yearimdb_score 两列进行排序,由大到小降序排列
movie3 = movie2.sort_values(['title_year','imdb_score'], ascending=False) movie3.head() 

输出结果

movie_title title_year imdb_score
4312 Kickboxer: Vengeance 2016.0 9.1
4277 A Beginner’s Guide to Snuff 2016.0 8.7
3798 Airlift 2016.0 8.5
27 Captain America: Civil War 2016.0 8.2
98 Godzilla Resurgence 2016.0 8.2
  • 用drop_duplicates去重,只保留每年的第一条数据
# df.drop_duplicates(subset='列名') # 对指定列的值去重,只保留第一个 movie_top_year = movie3.drop_duplicates(subset='title_year') movie_top_year.head() 

输出结果

movie_title title_year imdb_score
4312 Kickboxer: Vengeance 2016.0 9.1
3745 Running Forever 2015.0 8.6
4369 Queen of the Mountains 2014.0 8.7
3935 Batman: The Dark Knight Returns, Part 2 2013.0 8.4
3 The Dark Knight Rises 2012.0 8.5

2.3 关于sort_values多列排序

提取出每年,每种电影分级中预算少的电影

  • 多列排序时,ascending 参数传入一个列表,排序参数也是一个列表,并且一一对应
# 构造新的df,保留有效列 movie4 = movie[['movie_title', 'title_year', 'content_rating', 'budget']] # 分组:多列排序,ascending=[False, False, True] 降序,降序,升序 movie4_sorted = movie4.sort_values(['title_year', 'content_rating', 'budget'], ascending=[False, False, True]) # 去重:删除'title_year', 'content_rating'相同的数据 movie4_sorted.drop_duplicates(subset=['title_year', 'content_rating']).head(10) 

输出结果

movie_title title_year content_rating budget
4026 Compadres 2016.0 R .0
4658 Fight to the Finish 2016.0 PG-13 .0
4661 Rodeo Girl 2016.0 PG .0
3252 The Wailing 2016.0 Not Rated NaN
4659 Alleluia! The Devil’s Carnival 2016.0 NaN .0
4731 Bizarre 2015.0 Unrated .0
812 The Ridiculous 6 2015.0 TV-14 NaN
4831 The Gallows 2015.0 R .0
4825 Romantic Schemer 2015.0 PG-13 .0
3796 R.L. Stine’s Monsterville: The Cabinet of Souls 2015.0 PG .0

3 简单数据分析练习

租房数据

3.1 初步查探数据集信息

  • 载入数据,并查看列名
import pandas as pd house_data = pd.read_csv('data/LJdata.csv') house_data.columns # 输出结果如下 Index(['区域', '地址', '标题', '户型', '面积', '价格', '楼层', '建造时间', '朝向', '更新时间', '看房人数','备注', '链接地址'],dtype='object') 
  • 查看数据基本情况
house_data.head() # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rb4b6bF7-38)(./img/租房数据集练习-01.png)]

  • 查看数据集基本信息,每个字段值的数量,是否非空值,以及该字段的数据类型
house_data.info() # 输出结果如下 <class 'pandas.core.frame.DataFrame'> RangeIndex: 2760 entries, 0 to 2759 Data columns (total 13 columns): district 2760 non-null object address 2760 non-null object title 2760 non-null object house_type 2760 non-null object area 2760 non-null object price 2760 non-null int64 floor 2760 non-null object build_time 2758 non-null object direction 2760 non-null object update_time 2760 non-null object view_num 2760 non-null int64 extra_info 2760 non-null object link 2760 non-null object dtypes: int64(2), object(11) memory usage: 280.4+ KB 
  • 查看数据行列数量
house_data.shape # 输出结果如下 (2760, 13) 
  • 查看数据集中,所有数值字段的基本统计信息
house_data.describe() # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-huVtjWsh-40)(./img/租房数据集练习-02.png)]

  • 查看数据集中,所有非数值字段的基本统计信息
import numpy as np house_data.describe(include=[np.object, pd.Categorical]) #house_data.describe(include=[np.object, pd.Categorical]).T # 行列转换查看 # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uZpapyMn-41)(./img/租房数据集练习-03.png)]

3.2 找到租金最低和最高的房子的全部信息

3.2.1 方法1-通过指定的字段和字段值获取整行数据
  • 租金最低的房子
house_data[house_data['价格']==house_data['价格'].min()] # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ekTPseM9-42)(./img/租房数据集练习-04.png)]

  • 租金最高的房子
house_data[house_data['价格']==house_data['价格'].max()] # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lkw7zFOg-43)(./img/租房数据集练习-05.png)]

3.2.2 方法2-按指定字段的值进行排序
  • sort_values函数按照字段的值排序,ascending参数默认为True,由小到大升序,取第一个最小值的数据
house_data.sort_values(by='价格').head(1) # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oerd9hDi-44)(./img/租房数据集练习-04.png)]

  • sort_values函数按照字段的值排序,ascending参数默认为True,由小到大升序,取最后一个最大值的数据
house_data.sort_values(by='价格').tail(1) 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6HREJje-45)(./img/租房数据集练习-05.png)]

3.3 找到最近新上的5套房源

# 指定字段,由大到小升序,取前5 house_data.sort_values(by='更新时间', ascending=False).head(10) # 输出结果如下图 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oDbOCX3g-46)(./img/租房数据集练习-06.png)]

3.4 查看所有更新时间

# 查看指定字段的值,去重 house_data['更新时间'].unique() # 输出结果如下 array(['2017.07.21', '2017.07.23', '2017.07.20', '2017.07.25', '2017.07.26', '2017.07.16', '2017.07.22', '2017.07.24', '2017.07.27', '2017.07.19', '2017.07.14', '2017.07.15', '2017.07.17', '2017.07.18'], dtype=object) 

3.5 统计看房人数

  • 看房人数
print(house_data['看房人数'].mean()) # 平均值 print(house_data['看房人数'].median()) # 中位数 # 一组数据按从小到大的顺序依次排列,处在中间位置的一个数 # 输出结果如下 13.826 10.0 
  • 根据不同看房人数分别统计房源数量(分别统计相同看房人数的房源数量);参数as_index=False表示分组字段不作为行索引(默认为True),同时默认行索引
# 根据看房人数字段的值对标题字段做分组,对字段标题(房源)统计总数,行索引设为默认 tmp_df = house_data.groupby('看房人数', as_index=False)['标题'].count() tmp_df.columns = ['看房人数', '总和'] # 设置列名 tmp_df.head() # 输出结果如下 看房人数 总和 0 0 152 1 1 149 2 2 143 3 3 129 4 4 147 
  • 找到看房人数最多的区域,并计算该区域房源的看房总人数
# 按区域对看房人数进行分组,再计算看房人数字段值的综合,返回新的df,并设行索引为默认 new_df = house_data.groupby('区域',as_index=False)['看房人数'].sum() print(new_df.head()) # 按指定列的指定值返回df类型的数据:df[df['列名']==’具体的一个值‘] ;返回数据的行数不确定 new_df[new_df['看房人数']==new_df['看房人数'].max()] # 输出结果如下 区域 看房人数 0 CBD租房 108 1 七里庄租房 234 2 万寿路租房 119 3 万柳租房 397 4 三元桥租房 277 区域 看房人数 109 望京租房 1569 

3.6 房租价格分布

查看房租价格的平均值和中位数

print(house_data['价格'].mean()) #平均值 print(house_data['价格'].median()) #中位数 # 输出结果如下 7570.1 6000.0 

3.7 看房人数最多的朝向

可参看3.2.5小节最后的找到看房人数最多的区域,并计算该区域房源的看房总人数

popular_direction = house_data.groupby('朝向',as_index=False)['看房人数'].sum() popular_direction[popular_direction['看房人数']==popular_direction['看房人数'].max()] # 返回结果如下 朝向 看房人数 23 南 北 11785 

3.8 最受欢迎的户型

获取看房人数最多的户型,思路:

  • 按户型分组,然后对看房人数字段的值进行求和,返回新的dataframe
  • 根据指定的列(看房人数总和)和值(最大值)返回结果
# 后边我们会详细学习分组以及聚合,这里只是先让大家提前感受 tmp = house_data.groupby('户型', as_index=False).agg({ 
   '看房人数':'sum'}) tmp[tmp['看房人数']==tmp['看房人数'].max()] # 输出结果如下 户型 看房人数 5 2117589 

3.9 房子的平均租房价格-元/平米

# 通过计算添加一列 house_data['单价-元/平米'] = house_data['价格']/house_data['面积'] house_data['单价-元/平米'].mean() # 求平均值 # 输出结果如下 87.454 

3.10 热门小区

# 按指定列地址、看房人数取新的df,再按地址分组,求相同地址下看房人数值的总和,返回新的df address_df = house_data[['地址','看房人数']].groupby(['地址'],as_index=False).sum() # 按看房总人数由大到小倒序排序 address_df.sort_values(by='看房人数', ascending=False).head() # 返会结果如下 地址 看房人数 951 清芷园 246 369 卡布其诺 245 938 润枫水尚 217 1149 芍药居北里 194 743 新康园 186 

小结

  • 掌握在Pandas中计算常用统计量的方法
    • info 了解不同字段的条目数量,数据类型,是否缺失及内存占用情况
    • describe 计算数值类型数据的常用统计量
  • 了解使用pandas进行简单排序、分组、聚合等计算
    • nlargest 返回指定字段的前n个最大值
    • nsmallest 返回指定字段的前n个最小值
    • sort_values 指定字段,按值排序
    • groupby 按字段分组
    • agg 分组之后聚合
THE END

发表回复