【毕业设计】大数据电影数据分析可视化系统 - python 爬虫
文章目錄
- 0 前言
- 1 課題背景
- 2 項(xiàng)目效果展示
- 2.1 主界面展示
- 2.2電影數(shù)據(jù)查詢
- 2.3可視化展示
- 3 數(shù)據(jù)爬取
- 3.1 Requests
- 3.2 bs4
- 3.3 MySQL數(shù)據(jù)庫(kù)
- 4 可視化技術(shù)
- 4.1 Flask
- 4.2 ECharts
- 4.3 補(bǔ)充:不做成web系統(tǒng)
- 5 最后
0 前言
🔥 Hi,大家好,這里是丹成學(xué)長(zhǎng)的畢設(shè)系列文章!
🔥 對(duì)畢設(shè)有任何疑問(wèn)都可以問(wèn)學(xué)長(zhǎng)哦!
這兩年開(kāi)始,各個(gè)學(xué)校對(duì)畢設(shè)的要求越來(lái)越高,難度也越來(lái)越大… 畢業(yè)設(shè)計(jì)耗費(fèi)時(shí)間,耗費(fèi)精力,甚至有些題目即使是專業(yè)的老師或者碩士生也需要很長(zhǎng)時(shí)間,所以一旦發(fā)現(xiàn)問(wèn)題,一定要提前準(zhǔn)備,避免到后面措手不及,草草了事。
為了大家能夠順利以及最少的精力通過(guò)畢設(shè),學(xué)長(zhǎng)分享優(yōu)質(zhì)畢業(yè)設(shè)計(jì)項(xiàng)目,今天要分享的新項(xiàng)目是
🚩 基于大數(shù)據(jù)的電影數(shù)據(jù)爬取分析可視化系統(tǒng)
🥇學(xué)長(zhǎng)這里給一個(gè)題目綜合評(píng)分(每項(xiàng)滿分5分)
- 難度系數(shù):4分
- 工作量:4分
- 創(chuàng)新點(diǎn):3分
🧿 選題指導(dǎo), 項(xiàng)目分享:
https://gitee.com/yaa-dc/BJH/blob/master/gg/cc/README.md
1 課題背景
隨著互聯(lián)網(wǎng)的快速發(fā)展,越來(lái)越多的人喜歡在微博、知乎、豆瓣等社交網(wǎng)站上發(fā)表自己對(duì)某些事物的想法、態(tài)度或意見(jiàn)。用戶同時(shí)也會(huì)將自己購(gòu)買的產(chǎn)品或體驗(yàn)到的服務(wù),在這些社區(qū)式的網(wǎng)站上評(píng)價(jià),這樣通常會(huì)帶動(dòng)他人也前去購(gòu)買或體驗(yàn),形成口碑效應(yīng)。
社交應(yīng)用及網(wǎng)站上有源源不斷的信息發(fā)布,這些信息中隱含著大量對(duì)我們及企業(yè)有收集價(jià)值的資源。就像用戶評(píng)分和評(píng)價(jià)系統(tǒng)中,用戶不但會(huì)對(duì)作品進(jìn)行評(píng)比,還分享和傳播了作品信息。如果能夠獲取這些數(shù)據(jù)并對(duì)其進(jìn)行分析,可以讓人們挑選到滿意的書籍、選擇出一部精彩的電影,也可以幫助企業(yè)改進(jìn)產(chǎn)品的服務(wù)等。使用爬蟲程序可以高效地對(duì)社交網(wǎng)站上的信息進(jìn)行收集、組織和管理。豆瓣網(wǎng)作為社交網(wǎng)站的代表,提供了在圖書、電影和音樂(lè)等方面獨(dú)樹一幟的評(píng)分、推薦及比價(jià)體系,在社交網(wǎng)絡(luò)中產(chǎn)生了深遠(yuǎn)的影響。
2 項(xiàng)目效果展示
2.1 主界面展示
2.2電影數(shù)據(jù)查詢
管理員可對(duì)電影數(shù)據(jù)進(jìn)行查詢,可根據(jù)“最低評(píng)分”,“最高評(píng)分”,“上映年份”,“電影類型”,“上映地區(qū)”,“影名關(guān)鍵字”等標(biāo)簽進(jìn)行篩選、查詢。
2.3可視化展示
- 電影類型矩形圖:可以清楚的看到劇情,紀(jì)錄片,喜劇類型的電影所占比重較大。
- 上映年份漏斗圖:可以看到中國(guó)、美國(guó)上映地區(qū)較多。
- 上映年份分布、電影評(píng)分分布圖。
- 時(shí)間軸圖:可隨年份動(dòng)態(tài)變化效果。
- 地區(qū)類型分布餅狀圖
- 頻數(shù)統(tǒng)計(jì)詞云圖:可根據(jù)主演、導(dǎo)演、編劇和電影排名生成相應(yīng)的詞云圖
3 數(shù)據(jù)爬取
3.1 Requests
requests是Python用于網(wǎng)絡(luò)請(qǐng)求的第三庫(kù),也是爬蟲獲取網(wǎng)絡(luò)數(shù)據(jù)的重要工具,使用的時(shí)候需要導(dǎo)入
本項(xiàng)目中相關(guān)代碼:
import requests from bs4 import BeautifulSoup from lxml import htmletree = html.etree import csv# 請(qǐng)求頭 headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36" } hrefs = []# 爬取豆瓣電影TOP250的url # 獲取電影詳情頁(yè)url def get_film_url(url):try:r = requests.get(url, headers=headers)selector = etree.HTML(r.text)movie_hrefs = selector.xpath('//div[@class="hd"]/a/@href') # 電影的詳情地址for i in range(0, len(movie_hrefs)):hrefs.append(movie_hrefs[i])except Exception as e:print(e)# 保存電影鏈接url def save_url():try:# 獲取鏈接for href in hrefs:# 存入csvfile_path = "./豆瓣電影TOP250鏈接.csv"with open(file_path, "a+", newline='', encoding='gb18030') as csvfile:writer = csv.writer(csvfile)writer.writerow([href])except Exception as e:print(e)def main():# 爬取豆瓣電影TOP250的urlfor i in range(0, 250, 25):url = "https://movie.douban.com/top250?start=" + str(i) + ""get_film_url(url)save_url()if __name__ == '__main__':main()3.2 bs4
bs4即BeautifulSoup,是python種的一個(gè)庫(kù),最主要的內(nèi)容就是從網(wǎng)頁(yè)中抓取數(shù)據(jù)。
Beautiful Soup提供一些簡(jiǎn)單的、python式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹等功能。它是一個(gè)工具箱,通過(guò)解析文檔為用戶提供需要抓取的數(shù)據(jù),因?yàn)楹?jiǎn)單,所以不需要多少代碼就可以寫出一個(gè)完整的應(yīng)用程序。
Beautiful Soup自動(dòng)將輸入文檔轉(zhuǎn)換為Unicode編碼,輸出文檔轉(zhuǎn)換為utf-8編碼。你不需要考慮編碼方式,除非文檔沒(méi)有指定一個(gè)編碼方式,這時(shí),Beautiful Soup就不能自動(dòng)識(shí)別編碼方式了。然后,你僅僅需要說(shuō)明一下原始編碼方式就可以了。
Beautiful Soup已成為和lxml、html6lib一樣出色的python解釋器,為用戶靈活地提供不同的解析策略或強(qiáng)勁的速度。
3.3 MySQL數(shù)據(jù)庫(kù)
利用Pymysql,將爬取到的數(shù)據(jù)存入數(shù)據(jù)庫(kù)中,相關(guān)代碼如下:
# 打開(kāi)數(shù)據(jù)庫(kù)連接conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='douban', charset='utf8')# 使用cursor方法創(chuàng)建一個(gè)游標(biāo)cursor = conn.cursor()# # 執(zhí)行sql語(yǔ)句 # query = 'insert into tb_film(url, filmname, score, showtime, genres, areas, mins, directors, scriptwriters, actors, comments) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'query = 'insert into tb_film(url, filmname, score, showtime, genres, areas, directors, scriptwriters, actors, comments) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'values = (url, filmname, score, showtime, genres_list, area_list, directors_list, scriptwriters_list,actors_list,comment)cursor.execute(query, values)# 提交之前的操作,如果之前已經(jīng)執(zhí)行多次的execute,那么就都進(jìn)行提交conn.commit()4 可視化技術(shù)
4.1 Flask
Flask是一個(gè)基于Werkzeug和Jinja2的輕量級(jí)Web應(yīng)用程序框架。與其他同類型框架相比,Flask的靈活性、輕便性和安全性更高,而且容易上手,它可以與MVC模式很好地結(jié)合進(jìn)行開(kāi)發(fā)。Flask也有強(qiáng)大的定制性,開(kāi)發(fā)者可以依據(jù)實(shí)際需要增加相應(yīng)的功能,在實(shí)現(xiàn)豐富的功能和擴(kuò)展的同時(shí)能夠保證核心功能的簡(jiǎn)單。Flask豐富的插件庫(kù)能夠讓用戶實(shí)現(xiàn)網(wǎng)站定制的個(gè)性化,從而開(kāi)發(fā)出功能強(qiáng)大的網(wǎng)站。
本項(xiàng)目在Flask開(kāi)發(fā)后端時(shí),前端請(qǐng)求會(huì)遇到跨域的問(wèn)題,解決該問(wèn)題有修改數(shù)據(jù)類型為jsonp,采用GET方法,或者在Flask端加上響應(yīng)頭等方式,在此使用安裝Flask-CORS庫(kù)的方式解決跨域問(wèn)題。此外需要安裝請(qǐng)求庫(kù)axios。
部分相關(guān)代碼:
from flask import Flask from flask import request, redirect from flask import render_template, url_for from flask_paginate import Pagination from sqlalchemy import create_engine,Column,Integer,SmallInteger,String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() from list_data import select_score, select_showtime, select_genres, select_areas, film_data from genres import show_genres from areas import show_areas from showtime import show_showtime from score import show_score from timeline_score import show_score_top from timeline_comment import show_comment_top from select_showtime import select_showtime from select_showtime import showtime_group from film_search import film_searchapp = Flask(__name__) app.jinja_env.auto_reload = True app.config['TEMPLATES_AUTO_RELOAD'] = True#初始化數(shù)據(jù)庫(kù)連接 engine = create_engine("mysql+pymysql://root:123456@localhost:3306/douban?charset=utf8",echo = True) #創(chuàng)建緩存對(duì)象 Session =sessionmaker(bind=engine) session =Session #聲明基類 Base = declarative_base() #定義Film對(duì)象 #基于這個(gè)基類來(lái)創(chuàng)建我們的自定義類,一個(gè)類就是一個(gè)數(shù)據(jù)庫(kù)表; class Film(Base):#表的名字__tablename__= 'tb_film'#表的結(jié)構(gòu)id = Column(Integer,primary_key=True,autoincrement=True)url =Column(String(250))filmname =Column(String(50))score =Column(String)comments =Column(Integer)showtime =Column(Integer)genres =Column(String(20))areas =Column(String(20))actors =Column(String(50))directors =Column(String(50))scriptwriters =Column(String(50))@app.route('/') def index():# return render_template('pages/echarts/e1.html')# return render_template('index.html')return render_template('login.html')@app.route('/register') def register():# return render_template('pages/echarts/e1.html')# return render_template('index.html')return render_template('register.html')@app.route('/index') def welcom2index():# return render_template('pages/echarts/e1.html')return render_template('index.html')# return render_template('login.html')@app.route('/welcome') def welcome():print('done')return render_template('pages/welcome.html')@app.route("/page_none") def page_none():return render_template('page_none')# 驗(yàn)證用戶名和密碼 @app.route('/login', methods=['POST']) #@app.route('/index') def login():print(request.form['username'])# 需要從request對(duì)象讀取表單內(nèi)容:if request.form['username'] == 'admin' and request.form['password'] == '123456':return render_template('index.html')# 表單list @app.route("/list") @app.route("/list/") def list(limit=10):# 列表屬性t_low = select_score()[0]t_high = select_score()[1]t_showtime = select_showtime()t_genres = select_genres()t_areas = select_areas()# 分頁(yè)# limit = 15page = int(request.args.get("page", 1))start = (page - 1) * limitif request.args.get("low") or request.args.get("high") or request.args.get("showtime") or request.args.get("areas") or request.args.get("genres") or request.args.get("filmname"):# 參數(shù)選擇r_low = request.args.get("low")r_high = request.args.get("high")r_showtime = request.args.get("showtime")r_genres = request.args.get("genres")r_areas = request.args.get("areas")r_filmname = request.args.get("filmname")# 返回?cái)?shù)據(jù)print("參數(shù):{},{},{},{},{}".format(r_low, r_high, r_showtime, r_genres, r_areas,r_filmname))print("參數(shù)1:{}".format(type(r_low)))print("參數(shù)2:{}".format(len(r_low)))r_films = film_data(low=r_low, high=r_high, showtime=r_showtime, genres=r_genres, areas=r_areas, filmname=r_filmname)[0]r_row = film_data(low=r_low, high=r_high, showtime=r_showtime, genres=r_genres, areas=r_areas, filmname=r_filmname)[1]# 分頁(yè)r_end = page * limit if r_row > page * limit else r_rowr_paginate = Pagination(page=page, total=r_row)r_ret = r_films[start:r_end]return render_template('pages/order/list.html', low=t_low, high=t_high, showtime=t_showtime, genres=t_genres,areas=t_areas, films=r_ret, row=r_row,paginate=r_paginate)else:# 返回?cái)?shù)據(jù)films = film_data()[0]row = film_data()[1]end = page * limit if row > page * limit else rowpaginate = Pagination(page=page, total=row)ret=films[start:end]print("res:{}".format(ret))return render_template('pages/order/list.html', low=t_low, high=t_high, showtime=t_showtime, genres=t_genres,areas=t_areas, films=ret,row=row, paginate=paginate)4.2 ECharts
ECharts(Enterprise Charts)是百度開(kāi)源的數(shù)據(jù)可視化工具,底層依賴輕量級(jí)Canvas庫(kù)ZRender。兼容了幾乎全部常用瀏覽器的特點(diǎn),使它可廣泛用于PC客戶端和手機(jī)客戶端。ECharts能輔助開(kāi)發(fā)者整合用戶數(shù)據(jù),創(chuàng)新性的完成個(gè)性化設(shè)置可視化圖表。支持折線圖(區(qū)域圖)、柱狀圖(條狀圖)、散點(diǎn)圖(氣泡圖)、K線圖、餅圖(環(huán)形圖)等,通過(guò)導(dǎo)入 js 庫(kù)在 Java Web 項(xiàng)目上運(yùn)行。
數(shù)據(jù)預(yù)覽
import pandas as pd import json# =============================================加載數(shù)據(jù)===================================# 加載數(shù)據(jù) --credits credits = pd.read_csv('./tmdb_5000_credits.csv') print('credits:\n', credits) print('*' * 100) print('credits:\n', credits.columns) print('*' * 100) print('credits:\n', credits.info()) print('*' * 100)# 加載數(shù)據(jù) movies = pd.read_csv('./tmdb_5000_movies.csv') print('movies:\n', movies) print('#' * 100) print('movies:\n', movies.columns) print('#' * 100) print('movies:\n', movies.info()) print('#' * 100)合并數(shù)據(jù)集
先將 credits 數(shù)據(jù)集和 movie 數(shù)據(jù)集中的數(shù)據(jù)合并在一起,再查看合并后的數(shù)據(jù)集信息
代碼實(shí)現(xiàn):
# (1)合并數(shù)據(jù) # print(credits['crew']) # credits 中存在 movie_id 和 title # movies 中存在 id 和 title # 將 credits 中的 movie_id 修改為 id credits.rename(columns={'movie_id': 'id'}, inplace=True) # print('credits的列索引:\n', credits.columns) # 主鍵合并 ---on id 和 title all_data = pd.merge(left=credits, right=movies, on=['id', 'title'], how='outer') print('all_data:\n', all_data) print('all_data:\n', all_data.columns) print('all_data:\n', all_data.dtypes)選取子集
由于數(shù)據(jù)集中包含的信息過(guò)多,其中部分?jǐn)?shù)據(jù)并不是我們研究的重點(diǎn),所以從中選取我 們需要的數(shù)據(jù):
代碼實(shí)現(xiàn):
# 篩選特征 all_data = all_data['original_title', 'crew', 'release_date', 'genres', 'keywords','production_companies', 'production_countries', 'revenue','budget', 'runtime', 'vote_average'] print('all_data的列索引:\n', all_data.columns) print('all_data的形狀:\n', all_data.shape)由于后面的數(shù)據(jù)分析涉及到電影類型的利潤(rùn)計(jì)算,先求出每部電影的利潤(rùn),并在數(shù)據(jù)集 data 中增加 profit 數(shù)據(jù)列
代碼實(shí)現(xiàn):
# 增加利潤(rùn) all_data['profit'] = all_data['revenue'] - all_data['budget'] print('all_data的列索引:\n', all_data) print('all_data的形狀:\n', all_data)缺失值處理
代碼實(shí)現(xiàn):
# 檢測(cè)缺失值 # pd.isnull + sum res_null = pd.isnull(all_data).sum() print('缺失值檢測(cè)結(jié)果:\n', res_null)# 檢測(cè)到 release_date 存在一個(gè)缺失值 ---針對(duì)方式:填充,查找具體的電影名稱,根據(jù)電影名稱查找上映時(shí)間 # a、確定bool數(shù)組 mask = all_data.loc[:, 'release_date'].isnull() # b、根據(jù)bool數(shù)組來(lái)獲取缺失值位置的電影名稱 movie_name = all_data.loc[mask, 'title'] print('缺失上映日期的電影名稱為:\n', movie_name) # 缺失上映日期的電影名稱為: # 4553 America Is Still the Place # Name: title, dtype: object# 通過(guò)上網(wǎng)查詢?cè)撾娪暗纳嫌橙掌跒?#xff1a;2014-06-01 # c 、 填充 all_data.loc[mask, 'release_date'] = '2014-06-01'# 將 release_date 轉(zhuǎn)化為 pandas支持的時(shí)間序列 all_data.loc[:, 'release_date'] = pd.to_datetime(all_data.loc[:, 'release_date'])# 獲取 發(fā)行年份 all_data.loc[:, 'release_year'] = all_data.loc[:, 'release_date'].dt.year通過(guò)上面的結(jié)果信息可以知道:整個(gè)數(shù)據(jù)集缺失的數(shù)據(jù)比較少。 其中 release_date(首次上映日期)缺失 1 個(gè)數(shù)據(jù),可以通過(guò)網(wǎng)上查詢補(bǔ)齊這個(gè)數(shù)據(jù),填補(bǔ) release_date(首次上映日期)數(shù)據(jù)
數(shù)據(jù)格式轉(zhuǎn)換
genres 列數(shù)據(jù)處理:
代碼實(shí)現(xiàn):
# 查看電影風(fēng)格數(shù)據(jù) print('電影風(fēng)格:\n', all_data.loc[:, 'genres']) # json數(shù)據(jù)類型# json.loads # 可以將json轉(zhuǎn)化為python類型 # 將 all_data.loc[:, 'genres'] 由 json類型轉(zhuǎn)化為 python類型 all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(json.loads)# 構(gòu)建所有的電影的類型 all_movie_type = set()# 定義一個(gè)函數(shù),來(lái)提取電影類型 def get_movie_type(val):"""獲取電影類型:param val: 數(shù)據(jù):return: 提取之后的電影類型數(shù)據(jù)"""# 構(gòu)建一個(gè)空列表,用來(lái)存儲(chǔ)每一個(gè)電影的電影類型type_list = []# 遍歷 列表for item in val:# 如果item存在if item:# 獲取該電影的電影類型movie_type = item['name']# 將其加入到 type_listtype_list.append(movie_type)# 將其加入到 all_movie_typeall_movie_type.add(movie_type)return ','.join(type_list)# 調(diào)用 all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(get_movie_type)print('獲取電影類型之后的結(jié)果:\n', all_data.loc[:, 'genres'])# 將所有的電影類型轉(zhuǎn)化為 list all_movie_type = list(all_movie_type)# 遍歷 for column in all_movie_type:# 先增加all_data.loc[:, column] = 0# 構(gòu)建bool數(shù)組mask = all_data.loc[:, 'genres'].str.contains(column)# 修改all_data.loc[mask, column] = 1print('all_data:\n', all_data)數(shù)據(jù)可視化
繪制電影數(shù)據(jù)類型隨時(shí)間變化趨勢(shì)圖
import matplotlib.pyplot as plt# 創(chuàng)建畫布 plt.figure() # 默認(rèn)不支持中文 ---修改RC參數(shù) plt.rcParams['font.sans-serif'] = 'SimHei' # 增加字體之后變得不支持負(fù)號(hào),需要修改RC參數(shù)讓其繼續(xù)支持負(fù)號(hào) plt.rcParams['axes.unicode_minus'] = False # 構(gòu)建橫軸數(shù)據(jù) x = groupby_year.index for movie_type in groupby_year.columns:# 構(gòu)建縱軸數(shù)據(jù)y = groupby_year[movie_type]# 繪制折線圖plt.plot(x, y) # 增加標(biāo)題 plt.title('電影數(shù)據(jù)類型隨時(shí)間變化趨勢(shì)圖') # 設(shè)置圖例 plt.legend(groupby_year.columns, fontsize='x-small') # 設(shè)置縱軸名稱 plt.ylabel('數(shù)量') # 設(shè)置橫軸名稱 plt.xlabel('年份') # 增加網(wǎng)絡(luò)曲線 plt.grid(b=True, alpha=0.2) # 保存圖片 plt.savefig('./電影數(shù)據(jù)類型隨時(shí)間變化') # 展示 plt.show()
分析結(jié)論: 從圖中觀察到,隨著時(shí)間的推移,所有電影類型都呈現(xiàn)出增長(zhǎng)趨勢(shì),尤其是 1992 年以 后各個(gè)類型的電影均增長(zhǎng)迅速,其中 Drama(戲劇)和 Comedy(喜劇)增長(zhǎng)最快,目前仍是最熱 門的電影類型
繪制各種類型電影數(shù)量的統(tǒng)計(jì)柱狀圖
繪制各種電影類型的占比餅圖
電影類型平均利潤(rùn)數(shù)據(jù)可視化
# 可視化 ---比 各種電影類型 的 平均利潤(rùn) ---柱狀圖 # Pyecharts # 實(shí)例化對(duì)象 bar = Bar(# 初始化配置init_opts=opts.InitOpts(width='900px',height='600px',theme="white") )# 添加數(shù)據(jù) bar.add_xaxis(xaxis_data=res_series.index.tolist() )bar.add_yaxis(series_name=' ',yaxis_data=[float('%.2f' % i) for i in (res_series / 1000000)],color='#6495ED' )# 設(shè)置全局配置 bar.set_global_opts(# 標(biāo)題title_opts=opts.TitleOpts(title='各種電影類型利潤(rùn)統(tǒng)計(jì)柱狀圖',# subtitle='廣州分校Python0421班級(jí)'pos_left='center',pos_top='3%'),# 圖例legend_opts=opts.LegendOpts(is_show=False,),# 橫軸坐標(biāo)設(shè)置xaxis_opts=opts.AxisOpts(name='利潤(rùn)(百萬(wàn))'),# # 坐標(biāo)系設(shè)置yaxis_opts=opts.AxisOpts(name='電影類型') )# 設(shè)置系列配置 bar.set_series_opts(label_opts=opts.LabelOpts(is_show=True,position='right',color='#000000',formatter='{c}') ) # 反轉(zhuǎn)坐標(biāo)軸 bar.reversal_axis()# 生成文件 bar.render('./各種電影類型利潤(rùn)統(tǒng)計(jì)柱狀圖.html')分析結(jié)論:
從圖中觀察到,拍攝 Animation、Adventure、Fantasy 這三類電影盈利最好,而拍攝 Foreign、TV Movie 這兩類電影會(huì)存在虧本的風(fēng)險(xiǎn)
4.3 補(bǔ)充:不做成web系統(tǒng)
** 數(shù)據(jù)預(yù)覽**
import pandas as pd import json# =============================================加載數(shù)據(jù)===================================# 加載數(shù)據(jù) --credits credits = pd.read_csv('./tmdb_5000_credits.csv') print('credits:\n', credits) print('*' * 100) print('credits:\n', credits.columns) print('*' * 100) print('credits:\n', credits.info()) print('*' * 100)# 加載數(shù)據(jù) movies = pd.read_csv('./tmdb_5000_movies.csv') print('movies:\n', movies) print('#' * 100) print('movies:\n', movies.columns) print('#' * 100) print('movies:\n', movies.info()) print('#' * 100)合并數(shù)據(jù)集
先將 credits 數(shù)據(jù)集和 movie 數(shù)據(jù)集中的數(shù)據(jù)合并在一起,再查看合并后的數(shù)據(jù)集信息
代碼實(shí)現(xiàn):
# (1)合并數(shù)據(jù) # print(credits['crew']) # credits 中存在 movie_id 和 title # movies 中存在 id 和 title # 將 credits 中的 movie_id 修改為 id credits.rename(columns={'movie_id': 'id'}, inplace=True) # print('credits的列索引:\n', credits.columns) # 主鍵合并 ---on id 和 title all_data = pd.merge(left=credits, right=movies, on=['id', 'title'], how='outer') print('all_data:\n', all_data) print('all_data:\n', all_data.columns) print('all_data:\n', all_data.dtypes)選取子集
由于數(shù)據(jù)集中包含的信息過(guò)多,其中部分?jǐn)?shù)據(jù)并不是我們研究的重點(diǎn),所以從中選取我 們需要的數(shù)據(jù):
代碼實(shí)現(xiàn):
# 篩選特征 all_data = all_data['original_title', 'crew', 'release_date', 'genres', 'keywords','production_companies', 'production_countries', 'revenue','budget', 'runtime', 'vote_average'] print('all_data的列索引:\n', all_data.columns) print('all_data的形狀:\n', all_data.shape)由于后面的數(shù)據(jù)分析涉及到電影類型的利潤(rùn)計(jì)算,先求出每部電影的利潤(rùn),并在數(shù)據(jù)集 data 中增加 profit 數(shù)據(jù)列
代碼實(shí)現(xiàn):
# 增加利潤(rùn) all_data['profit'] = all_data['revenue'] - all_data['budget'] print('all_data的列索引:\n', all_data) print('all_data的形狀:\n', all_data)缺失值處理
代碼實(shí)現(xiàn):
# 檢測(cè)缺失值 # pd.isnull + sum res_null = pd.isnull(all_data).sum() print('缺失值檢測(cè)結(jié)果:\n', res_null)# 檢測(cè)到 release_date 存在一個(gè)缺失值 ---針對(duì)方式:填充,查找具體的電影名稱,根據(jù)電影名稱查找上映時(shí)間 # a、確定bool數(shù)組 mask = all_data.loc[:, 'release_date'].isnull() # b、根據(jù)bool數(shù)組來(lái)獲取缺失值位置的電影名稱 movie_name = all_data.loc[mask, 'title'] print('缺失上映日期的電影名稱為:\n', movie_name) # 缺失上映日期的電影名稱為: # 4553 America Is Still the Place # Name: title, dtype: object# 通過(guò)上網(wǎng)查詢?cè)撾娪暗纳嫌橙掌跒?#xff1a;2014-06-01 # c 、 填充 all_data.loc[mask, 'release_date'] = '2014-06-01'# 將 release_date 轉(zhuǎn)化為 pandas支持的時(shí)間序列 all_data.loc[:, 'release_date'] = pd.to_datetime(all_data.loc[:, 'release_date'])# 獲取 發(fā)行年份 all_data.loc[:, 'release_year'] = all_data.loc[:, 'release_date'].dt.year通過(guò)上面的結(jié)果信息可以知道:整個(gè)數(shù)據(jù)集缺失的數(shù)據(jù)比較少。 其中 release_date(首次上映日期)缺失 1 個(gè)數(shù)據(jù),可以通過(guò)網(wǎng)上查詢補(bǔ)齊這個(gè)數(shù)據(jù),填補(bǔ) release_date(首次上映日期)數(shù)據(jù)
數(shù)據(jù)格式轉(zhuǎn)換
genres 列數(shù)據(jù)處理:
代碼實(shí)現(xiàn):
# 查看電影風(fēng)格數(shù)據(jù) print('電影風(fēng)格:\n', all_data.loc[:, 'genres']) # json數(shù)據(jù)類型# json.loads # 可以將json轉(zhuǎn)化為python類型 # 將 all_data.loc[:, 'genres'] 由 json類型轉(zhuǎn)化為 python類型 all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(json.loads)# 構(gòu)建所有的電影的類型 all_movie_type = set()# 定義一個(gè)函數(shù),來(lái)提取電影類型 def get_movie_type(val):"""獲取電影類型:param val: 數(shù)據(jù):return: 提取之后的電影類型數(shù)據(jù)"""# 構(gòu)建一個(gè)空列表,用來(lái)存儲(chǔ)每一個(gè)電影的電影類型type_list = []# 遍歷 列表for item in val:# 如果item存在if item:# 獲取該電影的電影類型movie_type = item['name']# 將其加入到 type_listtype_list.append(movie_type)# 將其加入到 all_movie_typeall_movie_type.add(movie_type)return ','.join(type_list)# 調(diào)用 all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(get_movie_type)print('獲取電影類型之后的結(jié)果:\n', all_data.loc[:, 'genres'])# 將所有的電影類型轉(zhuǎn)化為 list all_movie_type = list(all_movie_type)# 遍歷 for column in all_movie_type:# 先增加all_data.loc[:, column] = 0# 構(gòu)建bool數(shù)組mask = all_data.loc[:, 'genres'].str.contains(column)# 修改all_data.loc[mask, column] = 1print('all_data:\n', all_data)數(shù)據(jù)可視化
繪制電影數(shù)據(jù)類型隨時(shí)間變化趨勢(shì)圖
import matplotlib.pyplot as plt# 創(chuàng)建畫布 plt.figure() # 默認(rèn)不支持中文 ---修改RC參數(shù) plt.rcParams['font.sans-serif'] = 'SimHei' # 增加字體之后變得不支持負(fù)號(hào),需要修改RC參數(shù)讓其繼續(xù)支持負(fù)號(hào) plt.rcParams['axes.unicode_minus'] = False # 構(gòu)建橫軸數(shù)據(jù) x = groupby_year.index for movie_type in groupby_year.columns:# 構(gòu)建縱軸數(shù)據(jù)y = groupby_year[movie_type]# 繪制折線圖plt.plot(x, y) # 增加標(biāo)題 plt.title('電影數(shù)據(jù)類型隨時(shí)間變化趨勢(shì)圖') # 設(shè)置圖例 plt.legend(groupby_year.columns, fontsize='x-small') # 設(shè)置縱軸名稱 plt.ylabel('數(shù)量') # 設(shè)置橫軸名稱 plt.xlabel('年份') # 增加網(wǎng)絡(luò)曲線 plt.grid(b=True, alpha=0.2) # 保存圖片 plt.savefig('./電影數(shù)據(jù)類型隨時(shí)間變化') # 展示 plt.show()
分析結(jié)論: 從圖中觀察到,隨著時(shí)間的推移,所有電影類型都呈現(xiàn)出增長(zhǎng)趨勢(shì),尤其是 1992 年以 后各個(gè)類型的電影均增長(zhǎng)迅速,其中 Drama(戲劇)和 Comedy(喜劇)增長(zhǎng)最快,目前仍是最熱 門的電影類型
繪制各種類型電影數(shù)量的統(tǒng)計(jì)柱狀圖
繪制各種電影類型的占比餅圖
電影類型平均利潤(rùn)數(shù)據(jù)可視化
# 可視化 ---比 各種電影類型 的 平均利潤(rùn) ---柱狀圖 # Pyecharts # 實(shí)例化對(duì)象 bar = Bar(# 初始化配置init_opts=opts.InitOpts(width='900px',height='600px',theme="white") )# 添加數(shù)據(jù) bar.add_xaxis(xaxis_data=res_series.index.tolist() )bar.add_yaxis(series_name=' ',yaxis_data=[float('%.2f' % i) for i in (res_series / 1000000)],color='#6495ED' )# 設(shè)置全局配置 bar.set_global_opts(# 標(biāo)題title_opts=opts.TitleOpts(title='各種電影類型利潤(rùn)統(tǒng)計(jì)柱狀圖',# subtitle='廣州分校Python0421班級(jí)'pos_left='center',pos_top='3%'),# 圖例legend_opts=opts.LegendOpts(is_show=False,),# 橫軸坐標(biāo)設(shè)置xaxis_opts=opts.AxisOpts(name='利潤(rùn)(百萬(wàn))'),# # 坐標(biāo)系設(shè)置yaxis_opts=opts.AxisOpts(name='電影類型') )# 設(shè)置系列配置 bar.set_series_opts(label_opts=opts.LabelOpts(is_show=True,position='right',color='#000000',formatter='{c}') ) # 反轉(zhuǎn)坐標(biāo)軸 bar.reversal_axis()# 生成文件 bar.render('./各種電影類型利潤(rùn)統(tǒng)計(jì)柱狀圖.html')5 最后
總結(jié)
以上是生活随笔為你收集整理的【毕业设计】大数据电影数据分析可视化系统 - python 爬虫的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 计算机说课比赛稿,《从军行》说课比赛稿
- 下一篇: 君子剑,怎样炼成?——再再谈岳不群