核對(duì)數(shù)據(jù)收集階段保存的douban_top250_demo.csv
文件,確認(rèn)與預(yù)期效果一致后缕溉,保存為douban_top250.csv
用于數(shù)據(jù)處理朵夏。
這樣可以避免在數(shù)據(jù)處理階段反復(fù)向豆瓣服務(wù)器發(fā)出數(shù)據(jù)請(qǐng)求稽莉,被反爬蟲機(jī)制屏蔽。
數(shù)據(jù)處理、分析和展示階段榆综,我們主要任務(wù)是格式化數(shù)據(jù)您觉,根據(jù)處理過的數(shù)據(jù)來制作相應(yīng)的分析圖像。需要導(dǎo)入以下幾個(gè)python
庫(kù):
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
from PIL import Image
from collections import Counter
from wordcloud import WordCloud, ImageColorGenerator
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn import linear_model
開始處理數(shù)據(jù)拖吼,大致操作思路如下:
先打開文件鳞上,再讀取整個(gè)文件,以逗號(hào)分割為列表對(duì)象吊档,然后轉(zhuǎn)化為250×7的ndarray
對(duì)象篙议,對(duì)應(yīng)7列數(shù)據(jù),每列250個(gè)元素怠硼,最后將其轉(zhuǎn)換為DataFrame
對(duì)象并加上每列的列名鬼贱,以方便后續(xù)調(diào)用。
with open('douban_top250.csv') as f: # 打開文件
text_f = f.read().strip() # 讀取文件得到str型文本
list_f = re.split('[,\n]', text_f) # 分割str文本并轉(zhuǎn)換為list型
array_f = np.array(list_f).reshape(250, 7) # 轉(zhuǎn)換為250×7的數(shù)組
columns_df_f = ['電影名稱', '評(píng)分', '評(píng)分人數(shù)', '上映年份', '國(guó)家', '類型', '短評(píng)'] # 列名
df_f = pd.DataFrame(array_f, columns=columns_df_f) # 轉(zhuǎn)為DataFrame類
print(df_f)
打印得到如下結(jié)果:
電影名稱 評(píng)分 評(píng)分人數(shù) 上映年份 國(guó)家 類型 \
0 肖申克的救贖 9.6 833069 1994 美國(guó) 犯罪 劇情
1 這個(gè)殺手不太冷 9.4 799185 1994 法國(guó) 劇情 動(dòng)作 犯罪
2 霸王別姬 9.5 595660 1993 中國(guó)大陸 香港 劇情 愛情 同性
3 阿甘正傳 9.4 684515 1994 美國(guó) 劇情 愛情
4 美麗人生 9.5 397936 1997 意大利 劇情 喜劇 愛情 戰(zhàn)爭(zhēng)
... ... ... ... ... ... ...
247 彗星來的那一夜 8.3 148590 2013 美國(guó) 英國(guó) 科幻 懸疑 驚悚
248 黑鷹墜落 8.5 100794 2001 美國(guó) 動(dòng)作 歷史 戰(zhàn)爭(zhēng)
249 假如愛有天意 8.2 215610 2003 韓國(guó) 劇情 愛情
短評(píng)
0 希望讓人自由香璃。
1 怪蜀黍和小蘿莉不得不說的故事这难。
... ...
248 還原真實(shí)而殘酷的戰(zhàn)爭(zhēng)。
249 瓊瑤阿姨在韓國(guó)的深刻版葡秒。
[250 rows x 7 columns]
片名匯總
DataFrame
類型的數(shù)據(jù)在提取列信息方面十分方便姻乓。
匯總榜單上所有電影的名字只需將df_f
對(duì)象的'電影名稱'
元素賦給變量即可。
titles = df_f['電影名稱'] # 提取片名列
print(titles)
打印結(jié)果如下:
0 肖申克的救贖
1 這個(gè)殺手不太冷
2 霸王別姬
3 阿甘正傳
4 美麗人生
5 千與千尋
...
244 廊橋遺夢(mèng)
245 罪惡之城
246 兩小無猜
247 彗星來的那一夜
248 黑鷹墜落
249 假如愛有天意
Name: 電影名稱, Length: 250, dtype: object
制片國(guó)家及影片類型信息處理
處理國(guó)家名及影片類型信息的方法與處理片名的方法大同小異眯牧。
countries = df_f['國(guó)家'] # 提取數(shù)組中的國(guó)家名數(shù)據(jù)
print(countries)
這里需要注意觀察返回的結(jié)果中的:
2 中國(guó)大陸 香港
可以看出存在一部影片有多個(gè)制作公司的情況蹋岩,如果要計(jì)數(shù)則需要解壓元素。
list_countries = ' '.join(countries).split() # 由于存在一部電影有多個(gè)制片國(guó)家学少,需要解壓出剪个。
print(list_countries)
得到列表類的結(jié)果如下:
['美國(guó)', '法國(guó)', '中國(guó)大陸', '香港', '美國(guó)', '意大利', ... ,'美國(guó)', '英國(guó)', '美國(guó)', '韓國(guó)']
對(duì)列表元素進(jìn)行計(jì)數(shù),使用內(nèi)置的collections
庫(kù)的Counter
將列表轉(zhuǎn)化為字典,其中key
為原列表中的元素旱易,value
為該元素在列表中出現(xiàn)的次數(shù)禁偎。
dict_countries0 = Counter(list_countries) # 轉(zhuǎn)換成字典類并計(jì)數(shù)
print(dict_countries0)
Counter({'美國(guó)': 143, '英國(guó)': 34, '日本': 29, '法國(guó)': 27,...,'博茨瓦納': 1, '愛爾蘭': 1})
這樣也可以很容易得到總共有多少個(gè)不同國(guó)家出現(xiàn):
total_countries = len(dict_countries0) # 字典長(zhǎng)度腿堤,即出現(xiàn)的不同國(guó)家個(gè)數(shù)
print(total_countries)
31
num_countries_show = 12 # 控制參數(shù),顯示國(guó)家的個(gè)數(shù)如暖,其余用“其他”來概括
dict_countries = list(dict_countries0.most_common(num_countries_show)) # 提取前12個(gè)
countries_rest = dict_countries0.most_common()[num_countries_show:] # 第12個(gè)以后合并為一項(xiàng)
size = [i[1] for i in dict_countries] #
size.append(sum(i[1] for i in countries_rest))
labels = [i[0] for i in dict_countries]
labels.append('其他')
榜單上影片的類型的數(shù)據(jù)處理與制片國(guó)家數(shù)據(jù)處理類似笆檀。
genres = df_f['類型']
list_genres = ' '.join(genres).split()
dict_genres0 = Counter(list_genres)
total_genres = len(dict_genres0)
num_genres_show = 14 # 控制參數(shù),顯示類型的個(gè)數(shù)盒至,其余用“其他”來概括
dict_genres = list(dict_genres0.most_common(num_genres_show))
genres_rest = dict_genres0.most_common()[num_genres_show:]
size = [i[1] for i in dict_genres]
size.append(sum(i[1] for i in genres_rest))
labels = [i[0] for i in dict_genres]
labels.append('其他')
上榜年份信息處理
在年份分析部分除了我們需要注意上榜年份為零的數(shù)據(jù)是不顯示的酗洒,需要我們另外添加。
date_movie = df_f['上映年份']
min_date = int(min(date_movie))
max_date = int(max(date_movie))
range_date = range(min_date, max_date + 1) # 上榜電影年份范圍
dict_date0 = Counter(date_movie) # 轉(zhuǎn)換為年份與對(duì)應(yīng)出現(xiàn)次數(shù)的字典
k = [int(key) for key in dict_date0.keys()] # 構(gòu)造上榜年份列表
list_date0 = {key: dict_date0[str(key)] if key in k else 0 for key in range_date} # 以零填充沒有上榜的年份的值
dict_date = Counter(list_date0) # 轉(zhuǎn)換為字典并計(jì)數(shù)
keys_date, values_date = list(list_date.keys()), list(list_date.values())
評(píng)分枷遂、評(píng)論人數(shù)處理
抓取得到的評(píng)分樱衷、評(píng)論人數(shù)的數(shù)據(jù)可直接調(diào)用,處理方法相對(duì)比較簡(jiǎn)單:
rate_movie = df_f['評(píng)分']
index_rate = rate_movie.index + 1 # 序號(hào)即排名(從1開始)
values_rate = rate_movie.values # 得到評(píng)分值列表
comments_count = df_f['評(píng)分人數(shù)']
values_comments = comments_count.values