为更好地提供数据支持的电影制作据,要求大家以TMDB 5000 Movie Dataset数据集为研究对象,完成以下数据可视化任务:
T1.2016年的总利润中,各电影类型所占的比例。当电影类型所占比例小于1%时,全部归到other类中。另外:利润=票房收入-预算。
此题与12周课堂作业类似,不同的是12周课堂作业用pyecharts绘图
import pandas as pd
import matplotlib.pyplot as plt # 导入绘图库
import matplotlib as mpl
import warnings
# 忽略警告。pandas很多时候会弹出警告,说某条命令即将在新版本中过期,建议换用新命令。如不想看到警告信息,可用此设置忽略
warnings.filterwarnings('ignore')
df = pd.read_excel('第十周课后作业(预处理后的数据).xlsx')
#df.info()
#提取年份为2016年的数据 预处理时已完成
df.dropna(inplace=True)
#df = df[(df['year'] == 2016)]
df.reset_index(inplace=True)
#计算利润=收入-预算 得出利润列(profit) 预处理时已完成
#df['profit'] = df['revenue'] - df['budget']
df
#df内容显示
#建立genres列表,提取电影的类型
genres_set = set()
for genre in df['genres'].str.split('|'):
for item in genre:
genres_set.add(item)
genres_list = list(genres_set)
#genres_list内容显示
['History', 'Family', 'Western', 'Science Fiction', 'Music', 'Thriller', 'Mystery', 'War', 'Adventure', 'Fantasy', 'Comedy', 'Horror', 'Animation', 'Action', 'Crime', 'Romance', 'Drama']
#初始化一个空列表
n = []
for i in range(0,df.shape[0]):
#df.shape[0]获取一维数组的长度 为104 即df的104行数据
n.append(len(df.loc[i,'genres'].split('|')))
#df.loc[i,'genres'].split('|') 选取df中第i行和'genres'列的元素,将该元素(一个以'|'分隔的字符串)分割成一个列表
#len(...)计算分割后得到列表的长度
#n.append(...)将计算得到的长度添加到列表n中
for genre in genres_list:
for i in range(0,df.shape[0]):
#遍历df的所有行 df.shape[0]返回df的行数104
if genre in df.loc[i,'genres']:
#判断从genres_list取出的电影类型是否在df的第i行的'genres'列中
df.loc[i,genre] = df.loc[i,'profit']/n[i]
#如果在,则df的第行的genre列的值为 第i行'profit'列的值÷该行电影类型数量n
#df.to_excel('profit2.xlsx')
#在df中选择列,列名在genres_list中,对选定的电影类型列进行求和,按降序排序返回一个新的series
profit_count = df.loc[:,genres_list].sum().sort_values(ascending = False,inplace = False)
#去掉小于或等于0的数据,上面显示最后两种类型数据小于0
profit_count = profit_count[profit_count>0]
#计算每个电影类型的总和的百分比:每个电影类型的值÷所有电影类型的值的总和
profit_perc_all = profit_count / profit_count.values.sum()
#创建一个新的series,包含大于或等于1%的百分比值
profit_perc_big = profit_perc_all[profit_perc_all >= 0.01]
#把小于百分之一的类型都加起来
other = profit_perc_all[profit_perc_all < 0.01].sum()
if other > 0:
profit_perc = pd.concat([profit_perc_big,pd.Series([other],index=['other'])])
else:
profit_perc = profit_perc_big
#profit_perc内容显示
Action 0.180260 Adventure 0.179390 Comedy 0.106625 Science Fiction 0.104806 Fantasy 0.094531 Family 0.090183 Animation 0.066331 Thriller 0.045158 Drama 0.042951 Horror 0.039865 Crime 0.021966 Romance 0.015690 Mystery 0.011574 other 0.000670 dtype: float64
#画图:饼图
#设置大小 像素
plt.rcParams['font.family'] = 'SimHei'
#创建一个新的图形,设置图形大小为宽12像素,高8像素 dpi为每英寸点数
plt.figure(figsize=(12,8),dpi=100)
plt.axes(aspect='equal') #保证饼图是个正圆
#定义explodes列表,用于设置饼图中每个扇区与中心之间的距离
#这里前9个0表示前9个扇区都不突出显示,后6个值表示会突出
explodes = [0,0,0,0,0,0,0,0,0,0.1,0.25,0.4,0.55,0.7]
plt.pie(profit_perc.values, #饼图数据
labels=profit_perc.index, #饼图标签
explode=explodes, #使用之前定义的突出显示的距离
autopct="%.2f%%", #自动计算并显示每个扇区的百分比,保留两位小数
shadow=True, #为饼图增加阴影效果
startangle=15, #设置饼图的起始角度为15°
labeldistance=1.1, #设置标签与饼图边缘的距离为1.1倍的饼图半径
textprops={'fontsize':12}) #设置文本字体大小为12
plt.title('2016年总利润中各电影类型所占比例',fontsize=18)
plt.savefig('2016年总利润中各电影类型所占比例_10周课后T1.png')
plt.show()
#饼图效果显示: