数据来自kaggle上tmdb5000电影数据集,本次数据分析主要包括电影数据可视化和简单的电影推荐模型,如:
1.电影类型分配及其随时间的变化
2.利润、评分、受欢迎程度直接的关系
3.哪些导演的电影卖座或较好
4.最勤劳的演职人员
5.电影关键字分析
6.电影相似性推荐

数据分析

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
import json
import warnings
warnings.filterwarnings('ignore')#忽略警告
movie = pd.read_csv('tmdb_5000_movies.csv')
credit = pd.read_csv('tmdb_5000_credits.csv')
movie.head(1)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

budget genres homepage id keywords original_language original_title overview popularity production_companies production_countries release_date revenue runtime spoken_languages status tagline title vote_average vote_count
0 237000000 [{“id”: 28, “name”: “Action”}, {“id”: 12, “nam… http://www.avatarmovie.com/ 19995 [{“id”: 1463, “name”: “culture clash”}, {“id”:… en Avatar In the 22nd century, a paraplegic Marine is di… 150.437577 [{“name”: “Ingenious Film Partners”, “id”: 289… [{“iso_3166_1”: “US”, “name”: “United States o… 2009-12-10 2787965087 162.0 [{“iso_639_1”: “en”, “name”: “English”}, {“iso… Released Enter the World of Pandora. Avatar 7.2 11800
movie.tail(3)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

budget genres homepage id keywords original_language original_title overview popularity production_companies production_countries release_date revenue runtime spoken_languages status tagline title vote_average vote_count
4800 0 [{“id”: 35, “name”: “Comedy”}, {“id”: 18, “nam… http://www.hallmarkchannel.com/signedsealeddel… 231617 [{“id”: 248, “name”: “date”}, {“id”: 699, “nam… en Signed, Sealed, Delivered “Signed, Sealed, Delivered” introduces a dedic… 1.444476 [{“name”: “Front Street Pictures”, “id”: 3958}… [{“iso_3166_1”: “US”, “name”: “United States o… 2013-10-13 0 120.0 [{“iso_639_1”: “en”, “name”: “English”}] Released NaN Signed, Sealed, Delivered 7.0 6
4801 0 [] http://shanghaicalling.com/ 126186 [] en Shanghai Calling When ambitious New York attorney Sam is sent t… 0.857008 [] [{“iso_3166_1”: “US”, “name”: “United States o… 2012-05-03 0 98.0 [{“iso_639_1”: “en”, “name”: “English”}] Released A New Yorker in Shanghai Shanghai Calling 5.7 7
4802 0 [{“id”: 99, “name”: “Documentary”}] NaN 25975 [{“id”: 1523, “name”: “obsession”}, {“id”: 224… en My Date with Drew Ever since the second grade when he first saw … 1.929883 [{“name”: “rusty bear entertainment”, “id”: 87… [{“iso_3166_1”: “US”, “name”: “United States o… 2005-08-05 0 90.0 [{“iso_639_1”: “en”, “name”: “English”}] Released NaN My Date with Drew 6.3 16
movie.info()#样本数量为4803,部分特征有缺失值
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4803 entries, 0 to 4802
Data columns (total 20 columns):
budget                  4803 non-null int64
genres                  4803 non-null object
homepage                1712 non-null object
id                      4803 non-null int64
keywords                4803 non-null object
original_language       4803 non-null object
original_title          4803 non-null object
overview                4800 non-null object
popularity              4803 non-null float64
production_companies    4803 non-null object
production_countries    4803 non-null object
release_date            4802 non-null object
revenue                 4803 non-null int64
runtime                 4801 non-null float64
spoken_languages        4803 non-null object
status                  4803 non-null object
tagline                 3959 non-null object
title                   4803 non-null object
vote_average            4803 non-null float64
vote_count              4803 non-null int64
dtypes: float64(3), int64(4), object(13)
memory usage: 750.5+ KB

样本数为4803,部分特征有缺失值,homepage,tagline缺损较多,但这俩不影响基本分析,release_date和runtime可以填充;仔细观察,部分样本的genres,keywords,production company特征值是[],需要注意。

credit.info

数据清理

数据特征中有很多特征为json格式,即类似于字典的键值对形式,为了方便后续处理,我们需要将其转换成便于python操作的str或者list形式,利于提取有用信息。

#movie genres电影流派,便于归类
movie['genres']=movie['genres'].apply(json.loads)
#apply function to axis in df,对df中某一行、列应用某种操作。
movie['genres'].head(1)
0    [{'id': 28, 'name': 'Action'}, {'id': 12, 'nam...
Name: genres, dtype: object
list(zip(movie.index,movie['genres']))[:2]
[(0,[{'id': 28, 'name': 'Action'},{'id': 12, 'name': 'Adventure'},{'id': 14, 'name': 'Fantasy'},{'id': 878, 'name': 'Science Fiction'}]),(1,[{'id': 12, 'name': 'Adventure'},{'id': 14, 'name': 'Fantasy'},{'id': 28, 'name': 'Action'}])]
for index,i in zip(movie.index,movie['genres']):list1=[]for j in range(len(i)):list1.append((i[j]['name']))# name:genres,Action...movie.loc[index,'genres']=str(list1)
movie.head(1)
#genres列已经不是json格式,而是将name将的value即电影类型提取出来重新赋值给genres
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

budget genres homepage id keywords original_language original_title overview popularity production_companies production_countries release_date revenue runtime spoken_languages status tagline title vote_average vote_count
0 237000000 [‘Action’, ‘Adventure’, ‘Fantasy’, ‘Science Fi… http://www.avatarmovie.com/ 19995 [{“id”: 1463, “name”: “culture clash”}, {“id”:… en Avatar In the 22nd century, a paraplegic Marine is di… 150.437577 [{“name”: “Ingenious Film Partners”, “id”: 289… [{“iso_3166_1”: “US”, “name”: “United States o… 2009-12-10 2787965087 162.0 [{“iso_639_1”: “en”, “name”: “English”}, {“iso… Released Enter the World of Pandora. Avatar 7.2 11800
#同样的方法应用到keywords列
movie['keywords'] = movie['keywords'].apply(json.loads)
for index,i in zip(movie.index,movie['keywords']):list2=[]for j in range(len(i)):list2.append(i[j]['name'])movie.loc[index,'keywords'] = str(list2)
#同理production_companies
movie['production_companies'] = movie['production_companies'].apply(json.loads)
for index,i in zip(movie.index,movie['production_companies']):list3=[]for j in range(len(i)):list3.append(i[j]['name'])movie.loc[index,'production_companies']=str(list3)
movie['production_countries'] = movie['production_countries'].apply(json.loads)
for index,i in zip(movie.index,movie['production_countries']):list3=[]for j in range(len(i)):list3.append(i[j]['name'])movie.loc[index,'production_countries']=str(list3)
movie['spoken_languages'] = movie['spoken_languages'].apply(json.loads)
for index,i in zip(movie.index,movie['spoken_languages']):list3=[]for j in range(len(i)):list3.append(i[j]['name'])movie.loc[index,'spoken_languages']=str(list3)
movie.head(1)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

budget genres homepage id keywords original_language original_title overview popularity production_companies production_countries release_date revenue runtime spoken_languages status tagline title vote_average vote_count
0 237000000 [‘Action’, ‘Adventure’, ‘Fantasy’, ‘Science Fi… http://www.avatarmovie.com/ 19995 [‘culture clash’, ‘future’, ‘space war’, ‘spac… en Avatar In the 22nd century, a paraplegic Marine is di… 150.437577 [‘Ingenious Film Partners’, ‘Twentieth Century… [‘United States of America’, ‘United Kingdom’] 2009-12-10 2787965087 162.0 [‘English’, ‘Español’] Released Enter the World of Pandora. Avatar 7.2 11800
credit.head(1)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

movie_id title cast crew
0 19995 Avatar [{“cast_id”: 242, “character”: “Jake Sully”, “… [{“credit_id”: “52fe48009251416c750aca23”, “de…
credit['cast'] = credit['cast'].apply(json.loads)
for index,i in zip(credit.index,credit['cast']):list3=[]for j in range(len(i)):list3.append(i[j]['name'])credit.loc[index,'cast']=str(list3)
credit['crew'] = credit['crew'].apply(json.loads)
#提取crew中director,增加电影导演一列,用作后续分析
def director(x):for i in x:if i['job'] == 'Director':return i['name']
credit['crew']=credit['crew'].apply(director)
credit.rename(columns={'crew':'director'},inplace=True)
credit.head(1)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

movie_id title cast director
0 19995 Avatar [‘Sam Worthington’, ‘Zoe Saldana’, ‘Sigourney … James Cameron

观察movie中id和credit中movie_id相同,可以将两个表合并,将所有信息统一在一个表中。

fulldf = pd.merge(movie,credit,left_on='id',right_on='movie_id',how='left')
fulldf.head(1)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

budget genres homepage id keywords original_language original_title overview popularity production_companies spoken_languages status tagline title_x vote_average vote_count movie_id title_y cast director
0 237000000 [‘Action’, ‘Adventure’, ‘Fantasy’, ‘Science Fi… http://www.avatarmovie.com/ 19995 [‘culture clash’, ‘future’, ‘space war’, ‘spac… en Avatar In the 22nd century, a paraplegic Marine is di… 150.437577 [‘Ingenious Film Partners’, ‘Twentieth Century… [‘English’, ‘Español’] Released Enter the World of Pandora. Avatar 7.2 11800 19995 Avatar [‘Sam Worthington’, ‘Zoe Saldana’, ‘Sigourney … James Cameron

1 rows × 24 columns

fulldf.shape

(4803, 24)

#观察到有相同列title,合并后自动命名成title_x,title_y
fulldf.rename(columns={'title_x':'title'},inplace=True)
fulldf.drop('title_y',axis=1,inplace=True)
#缺失值
NAs = pd.DataFrame(fulldf.isnull().sum())
NAs[NAs.sum(axis=1)>0].sort_values(by=[0],ascending=False)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

0
homepage 3091
tagline 844
director 30
overview 3
runtime 2
release_date 1
#补充release_date
fulldf.loc[fulldf['release_date'].isnull(),'title']

4553 America Is Still the Place Name: title, dtype: object

#上网查询补充
fulldf['release_date']=fulldf['release_date'].fillna('2014-06-01')
#runtime为电影时长,按均值补充
fulldf['runtime'] = fulldf['runtime'].fillna(fulldf['runtime'].mean())
#为方便分析,将release_date(object)转为datetime类型,并提取year,month
fulldf['release_year'] = pd.to_datetime(fulldf['release_date'],format='%Y-%m-%d').dt.year
fulldf['release_month'] = pd.to_datetime(fulldf['release_date'],format='%Y-%m-%d').dt.month

数据探索

#电影类型genres
#观察其格式,我们需要做str相关处理,先移除两边中括号
#相邻类型间有空格,需要移除
#再移除单引号,并按,分割提取即可
fulldf['genres']=fulldf['genres'].str.strip('[]').str.replace(" ","").str.replace("'","")
#每种类型现在以,分割
fulldf['genres']=fulldf['genres'].str.split(',')
list1=[]
for i in fulldf['genres']:list1.extend(i)
gen_list=pd.Series(list1).value_counts()[:10].sort_values(ascending=False)
gen_df = pd.DataFrame(gen_list)
gen_df.rename(columns={0:'Total'},inplace=True)
fulldf.ix[4801]
  budget                                                                  0
genres                                                                 []
homepage                                      http://shanghaicalling.com/
id                                                                 126186
keywords                                                               []
original_language                                                      en
original_title                                           Shanghai Calling
overview                When ambitious New York attorney Sam is sent t...
popularity                                                       0.857008
production_companies                                                   []
production_countries                ['United States of America', 'China']
release_date                                                   2012-05-03
revenue                                                                 0
runtime                                                                98
spoken_languages                                              ['English']
status                                                           Released
tagline                                          A New Yorker in Shanghai
title                                                    Shanghai Calling
vote_average                                                          5.7
vote_count                                                              7
movie_id                                                           126186
cast                    ['Daniel Henney', 'Eliza Coupe', 'Bill Paxton'...
director                                                      Daniel Hsia
release_year                                                         2012
release_month                                                           5
Name: 4801, dtype: object
plt.subplots(figsize=(10,8))
sns.barplot(y=gen_df.index,x='Total',data=gen_df,palette='GnBu_d')
plt.xticks(fontsize=15)#设置刻度字体大小
plt.yticks(fontsize=15)
plt.xlabel('Total',fontsize=15)
plt.ylabel('Genres',fontsize=15)
plt.title('Top 10 Genres',fontsize=20)
plt.show()

数量最多的前10种电影类型,有剧情、喜剧、惊悚、动作等,也是目前影院常见电影类型,那这些电影类型数量较多的背后原因有哪些呢?
我们再看看电影数量和时间的关系。

#对电影类型去重
l=[]
for i in list1:if i not in l:l.append(i)
#l.remove("")#有部分电影类型为空
len(l)#l就是去重后的电影类型

21

year_min = fulldf['release_year'].min()
year_max = fulldf['release_year'].max()year_genr =pd.DataFrame(index=l,columns=range(year_min,year_max+1))#生成类型为index,年份为列的dataframe,用于每种类型在各年份的数量
year_genr.fillna(value=0,inplace=True)#初始值为0intil_y = np.array(fulldf['release_year'])#用于遍历所有年份
z = 0
for i in fulldf['genres']:splt_gen = list(i)#每一部电影的所有类型for j in splt_gen:year_genr.loc[j,intil_y[z]] = year_genr.loc[j,intil_y[z]]+1#计数该类型电影在某一年份的数量z+=1
year_genr = year_genr.sort_values(by=2006,ascending=False)
year_genr = year_genr.iloc[0:10,-49:-1]
year_genr
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
Drama 7 8 3 6 4 3 2 4 8 5 97 106 122 115 99 79 110 110 95 37
Comedy 3 4 1 3 3 3 3 3 3 1 67 82 97 87 82 80 71 62 52 26
Thriller 3 2 3 1 2 1 1 2 4 5 53 55 59 56 69 58 53 66 67 27
Action 4 4 4 1 2 1 1 2 6 5 44 46 51 49 58 43 56 54 46 39
Romance 2 1 3 0 1 2 1 2 2 3 37 38 57 45 30 39 25 24 23 9
Family 0 0 1 0 0 1 0 1 0 1 20 29 28 29 28 17 22 23 17 9
Crime 3 0 2 3 2 2 0 2 0 0 28 33 32 30 24 27 37 27 26 10
Adventure 2 3 1 2 1 2 2 2 5 4 25 37 36 30 32 25 36 37 35 23
Fantasy 0 0 1 0 0 0 1 0 2 2 19 20 22 21 15 19 21 16 10 13
Horror 0 0 1 1 1 1 1 1 3 4 27 21 30 27 24 33 25 21 33 20

10 rows × 48 columns

plt.subplots(figsize=(10,8))
plt.plot(year_genr.T)
plt.title('Genres vs Time',fontsize=20)
plt.xticks(range(1969,2020,5))
plt.legend(year_genr.T)
plt.show()

可以看到,从1994年左右,电影进入繁荣发展时期,各种类型的电影均有大幅增加,而增加最多的又以剧情、喜剧、惊悚、动作等类型电影,可见,这些类型电影数量居多和电影艺术整体繁荣发展有一定关系。

#为了方便分析,构造一个新的dataframe,选取部分特征,分析这些特征和电影类型的关系。
partdf = fulldf[['title','vote_average','vote_count','release_year','popularity','budget','revenue']].reset_index(drop=True)
partdf.head(2)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

title vote_average vote_count release_year popularity budget revenue
0 Avatar 7.2 11800 2009 150.437577 237000000 2787965087
1 Pirates of the Caribbean: At World’s End 6.9 4500 2007 139.082615 300000000 961000000

因为一部电影可能有多种电影类型,将每种类型加入column中,对每部电影,是某种类型就赋值1,不是则赋值0

for per in l:partdf[per]=0z=0for gen in fulldf['genres']:if per in list(gen):partdf.loc[z,per] = 1else:partdf.loc[z,per] = 0z+=1
partdf.head(2)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

title vote_average vote_count release_year popularity budget revenue Action Adventure Fantasy Romance Horror Mystery History War Music Documentary Foreign TVMovie
0 Avatar 7.2 11800 2009 150.437577 237000000 2787965087 1 1 1 0 0 0 0 0 0 0 0 0 0
1 Pirates of the Caribbean: At World’s End 6.9 4500 2007 139.082615 300000000 961000000 1 1 1 0 0 0 0 0 0 0 0 0 0

2 rows × 28 columns

现在我们想了解每种电影类型一些特征的平均值,创建一个新的dataframe,index就是电影类型,列是平均特征,如平分vote,收入revenue,受欢迎程度等。

mean_gen = pd.DataFrame(l)
#点评分数取均值
newArray = []*len(l)
for genre in l:newArray.append(partdf.groupby(genre, as_index=True)['vote_average'].mean())
#现在newArray中是按类型[0]平均值[1]平均值存放,我们只关心[1]的值。
newArray2 = []*len(l)
for i in range(len(l)):newArray2.append(newArray[i][1])mean_gen['mean_votes_average']=newArray2
mean_gen.head(2)
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

0 mean_votes_average
0 Action 5.989515
1 Adventure 6.156962
#同理,用到别的特征上
#预算budget
newArray = []*len(l)
for genre in l:newArray.append(partdf.groupby(genre, as_index=True)['budget'].mean())
newArray2 = []*len(l)
for i in range(len(l)):newArray2.append(newArray[i][1])mean_gen['mean_budget']=newArray2
#收入revenue
newArray = []*len(l)
for genre in l:newArray.append(partdf.groupby(genre, as_index=True)['revenue'].mean())
newArray2 = []*len(l)
for i in range(len(l)):newArray2.append(newArray[i][1])mean_gen['mean_revenue']=newArray2
#popularity:相关页面查看次数
newArray = []*len(l)
for genre in l:newArray.append(partdf.groupby(genre, as_index=True)['popularity'].mean())
newArray2 = []*len(l)
for i in range(len(l)):newArray2.append(newArray[i][1])mean_gen['mean_popular']=newArray2
#vote_count:评分次数取count
newArray = []*len(l)
for genre in l:newArray.append(partdf.groupby(genre, as_index=True)['vote_count'].count())
newArray2 = []*len(l)
for i in range(len(l)):newArray2.append(newArray[i][1])mean_gen['vote_count']=newArray2
mean_gen.rename(columns={0:'genre'},inplace=True)
mean_gen.replace('','none',inplace=True)
#none代表有些电影类型或其他特征有缺失,可以看到数量很小,我们将其舍得不考虑
mean_gen.drop(20,inplace=True)
mean_gen['vote_count'].describe()

count 20.000000
mean 608.000000
std 606.931974
min 8.000000
25% 174.750000
50% 468.500000
75% 816.000000
max 2297.000000
Name: vote_count, dtype: float64

mean_gen['mean_votes_average'].describe()

count 20.000000
mean 6.173921
std 0.278476
min 5.626590
25% 6.009644
50% 6.180978
75% 6.344325
max 6.719797
Name: mean_votes_average, dtype: float64

#fig = plt.figure(figsize=(10, 8))
f,ax = plt.subplots(figsize=(10,6))
ax1 = f.add_subplot(111)
ax2 = ax1.twinx()
grid1 = sns.factorplot(x='genre', y='mean_votes_average',data=mean_gen,ax=ax1)
ax1.axes.set_ylabel('votes_average')
ax1.axes.set_ylim((4,7))grid2 = sns.factorplot(x='genre',y='mean_popular',data=mean_gen,ax=ax2,color='blue')
ax2.axes.set_ylabel('popularity')
ax2.axes.set_ylim((0,40))
ax1.set_xticklabels(mean_gen['genre'],rotation=90)plt.show()

从上图可知,外国电影并不受欢迎,虽然评分不低,但也是因为评分人数太少,动漫电影(Animation)、科幻(Science Fiction)、奇幻电影(Fantasy)、动作片(Action)受欢迎程度较高,评分也不低,数量最多的剧情片评分很高,但受欢迎程度较低,猜测可能大部分剧情片不是商业类型。

mean_gen['profit'] = mean_gen['mean_revenue']-mean_gen['mean_budget']
s = mean_gen['profit'].sort_values(ascending=False)[:10]
pdf = mean_gen.ix[s.index]plt.subplots(figsize=(10,6))
sns.barplot(x='profit',y='genre',data=pdf,palette='BuGn_r')
plt.xticks(fontsize=15)#设置刻度字体大小
plt.yticks(fontsize=15)
plt.xlabel('Profit',fontsize=15)
plt.ylabel('Genres',fontsize=15)
plt.title('Top 10 Profit of Genres',fontsize=20)plt.show()

可以看出,动画、探险、家庭和科幻是最赚钱的电影类型,适合去电影院观看,同时也是受欢迎的类型,那么我们看看变量的关系。

cordf = partdf.drop(l,axis=1)
cordf.columns#含有我们想了解的特征,适合分析
 Index(['title', 'vote_average', 'vote_count', 'release_year', 'popularity','budget', 'revenue'],dtype='object')
corrmat = cordf.corr()
f, ax = plt.subplots(figsize=(10,7))
sns.heatmap(corrmat,cbar=True, annot=True,vmax=.8, cmap='PuBu',square=True)

从上图可以看出,评分次数和受欢迎程度有比较强的关系,证明看的人多参与度也高,预算和票房也关系较强,票房和受欢迎程度、评分次数也有比较强的关系,为电影做好宣传很重要,我们再进一步看一下。

#budget, revenue在数据中都有为0的项,我们去除这些脏数据,
partdf = partdf[partdf['budget']>0]
partdf = partdf[partdf['revenue']>0]
partdf = partdf[partdf['vote_count']>3]
plt.subplots(figsize=(6,5))plt.xlabel('Budget',fontsize=15)
plt.ylabel('Revenue',fontsize=15)
plt.title('Budget vs Revenue',fontsize=20)
sns.regplot(x='budget',y='revenue',data=partdf,ci=None)

plt.subplots(figsize=(6,5))
plt.xlabel('vote_average',fontsize=15)
plt.ylabel('popularity',fontsize=15)
plt.title('Score vs Popular',fontsize=20)
sns.regplot(x='vote_average',y='popularity',data=partdf)

可以看出,成本和票房、评分高低和受欢迎程度还是呈线性关系的。但成本较低的电影,成本对票房的影响不大,评分高的的电影基本上也很受欢迎,我们再看看究竟是哪几部电影最挣钱、最受欢迎、口碑最好。

print(partdf.loc[partdf['revenue']==partdf['revenue'].max()]['title'])
print(partdf.loc[partdf['popularity']==partdf['popularity'].max()]['title'])
print(partdf.loc[partdf['vote_average']==partdf['vote_average'].max()]['title'])

0 Avatar
Name: title, dtype: object
546 Minions
Name: title, dtype: object
1881 The Shawshank Redemption
Name: title, dtype: object

partdf['profit'] = partdf['revenue']-partdf['budget']
print(partdf.loc[partdf['profit']==partdf['profit'].max()]['title'])

0 Avatar
Name: title, dtype: object

小黄人电影最受欢迎,阿凡达最赚钱,肖申克的救赎口碑最好。

s1 = cordf.groupby(by='release_year').budget.sum()
s2 = cordf.groupby(by='release_year').revenue.sum()
sdf = pd.concat([s1,s2],axis=1)
sdf = sdf.iloc[-39:-2]
plt.plot(sdf)
plt.xticks(range(1979,2020,5))
plt.legend(sdf)
plt.show()

电影业果然是蓬勃发展啊!现在大制作的电影越来越多,看来是有原因的啊!

对于科幻迷们,也可以看看最受欢迎的科幻电影都有哪些:

#最受欢迎的科幻电影
s = partdf.loc[partdf['ScienceFiction']==1,'popularity'].sort_values(ascending=False)[:10]
sdf = partdf.ix[s.index]
sns.barplot(x='popularity',y='title',data=sdf)
plt.show()

星际穿越最受欢迎,银河护卫队紧随其后,同理,我们也可以了解其他电影类型的情况。现在。让我们再看看电影人对电影市场的影响,一部好电影离不开台前幕后工作人员的贡献,是每一位优秀的电影人为我们带来好看的电影,这里,我们主要分析导演和演员。

#平均票房最高的导演
rev_d = fulldf.groupby('director')['revenue'].mean()
top_rev_d = rev_d.sort_values(ascending=False).head(20)
top_rev_d = pd.DataFrame(top_rev_d)
plt.subplots(figsize=(10,6))
sns.barplot(x='revenue',y=top_rev_d.index,data=top_rev_d,palette='BuGn_r')
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.xlabel('Average Revenue',fontsize=15)
plt.ylabel('Director',fontsize=15)
plt.title('Top 20 Revenue by Director',fontsize=20)
plt.show()

如图是市场好的导演,那么电影产量最高、或者既叫好又叫座的导演有哪些呢?

list2 = fulldf[fulldf['director']!=''].director.value_counts()[:10].sort_values(ascending=True)
list2 = pd.Series(list2)
list2

Oliver Stone 14
Renny Harlin 15
Steven Soderbergh 15
Robert Rodriguez 16
Spike Lee 16
Ridley Scott 16
Martin Scorsese 20
Clint Eastwood 20
Woody Allen 21
Steven Spielberg 27
Name: director, dtype: int64

plt.subplots(figsize=(10,6))
ax = list2.plot.barh(width=0.85,color='y')
for i,v in enumerate(list2.values):ax.text(.5, i, v,fontsize=12,color='white',weight='bold')
ax.patches[9].set_facecolor('g')
plt.title('Directors with highest movies')
plt.show()

top_vote_d = fulldf[fulldf['vote_average']>=8].sort_values(by='vote_average',ascending=False)
top_vote_d = top_vote_d.dropna()
top_vote_d = top_vote_d.loc[:,['director','vote_average']]
tmp = rev_d.sort_values(ascending=False)
vote_rev_d = tmp[tmp.index.isin(list(top_vote_d['director']))]
vote_rev_d = vote_rev_d.sort_values(ascending=False)
vote_rev_d = pd.DataFrame(vote_rev_d)
plt.subplots(figsize=(10,6))
sns.barplot(x='revenue',y=vote_rev_d.index,data=vote_rev_d,palette='BuGn_r')
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.xlabel('Average Revenue',fontsize=15)
plt.ylabel('Director',fontsize=15)
plt.title('Revenue by vote above 8 Director',fontsize=20)
plt.show()

再看看演职人员,cast特征里每一部电影有很多演职人员,幸运的是,cast是按演职人员的重要程度排序的,那么排名靠前的我们可以认为是主要演员。

fulldf['cast']=fulldf['cast'].str.strip('[]').str.replace(' ','').str.replace("'",'').str.replace('"','')
fulldf['cast']=fulldf['cast'].str.split(',')
list1=[]
for i in fulldf['cast']:list1.extend(i)
list1 = pd.Series(list1)
list1 = list1.value_counts()[:15].sort_values(ascending=True)
plt.subplots(figsize=(10,6))
ax = list1.plot.barh(width=0.9,color='green')
for i,v in enumerate(list1.values):ax.text(.8, i, v,fontsize=10,color='white',weight='bold')
plt.title('Actors with highest appearance')
ax.patches[14].set_facecolor('b')
plt.show()

fulldf['keywords'][2]

“[‘spy’, ‘based on novel’, ‘secret agent’, ‘sequel’, ‘mi6’, ‘british secret service’, ‘united kingdom’]”

from wordcloud import WordCloud, STOPWORDS
import nltk
from nltk.corpus import stopwords
#如果stopwords报错没有安装,可以在anaconda cmd中import nltk;nltk.download()
#在弹出窗口中选择corpa,stopword,刷新并下载
import io
from PIL import Image
plt.subplots(figsize=(12,12))
stop_words=set(stopwords.words('english'))
stop_words.update(',',';','!','?','.','(',')','$','#','+',':','...',' ','')img1 = Image.open('timg1.jpg')
hcmask1 = np.array(img1)
words=fulldf['keywords'].dropna().apply(nltk.word_tokenize)
word=[]
for i in words:word.extend(i)
word=pd.Series(word)
word=([i for i in word.str.lower() if i not in stop_words])
wc = WordCloud(background_color="black", max_words=4000, mask=hcmask1,stopwords=STOPWORDS, max_font_size= 60)
wc.generate(" ".join(word))plt.imshow(wc,interpolation="bilinear")
plt.axis('off')
plt.figure()
plt.show()

我们可以对关键词有大概了解,女性导演、独立电影占比较大,这也可能是电影的一个发展趋势。

电影推荐模型

现在我们根据上述的分析,可以考虑做一个电影推荐,通常来说,我们在搜索电影时,我们会去找同类的电影、或者同一导演演员的电影、或者评分较高的电影,那么需要的特征有genres,cast,director,score

l[:5]

[‘Action’, ‘Adventure’, ‘Fantasy’, ‘ScienceFiction’, ‘Crime’]

特征向量化

genre

def binary(genre_list):binaryList = []for genre in l:if genre in genre_list:binaryList.append(1)else:binaryList.append(0)return binaryList
fulldf['genre_vec'] = fulldf['genres'].apply(lambda x: binary(x))
fulldf['genre_vec'][0]

[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

cast

for i,j in zip(fulldf['cast'],fulldf.index):
    list2=[]
    list2=i[:4]
    list2.sort()
    fulldf.loc[j,'cast']=str(list2)
fulldf['cast'][0]

“[‘SamWorthington’, ‘SigourneyWeaver’, ‘StephenLang’, ‘ZoeSaldana’]”

fulldf['cast']=fulldf['cast'].str.strip('[]').str.replace(' ','').str.replace("'",'')
fulldf['cast']=fulldf['cast'].str.split(',')
fulldf['cast'][0]

[‘SamWorthington’, ‘SigourneyWeaver’, ‘StephenLang’, ‘ZoeSaldana’]

castList = []
for index, row in fulldf.iterrows():cast = row["cast"]for i in cast:if i not in castList:castList.append(i)
len(castList)

7515

def binary(cast_list):binaryList = []for genre in castList:if genre in cast_list:binaryList.append(1)else:binaryList.append(0)return binaryList
fulldf['cast_vec'] = fulldf['cast'].apply(lambda x:binary(x))
fulldf['cast_vec'].head(2)

0 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
1 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, …
Name: cast_vec, dtype: object

director

fulldf['director'][0]

‘James Cameron’

def xstr(s):if s is None:return ''return str(s)
fulldf['director']=fulldf['director'].apply(xstr)
directorList=[]
for i in fulldf['director']:if i not in directorList:directorList.append(i)
def binary(director_list):binaryList = []for direct in directorList:if direct in director_list:binaryList.append(1)else:binaryList.append(0)return binaryList
fulldf['director_vec'] = fulldf['director'].apply(lambda x:binary(x))

keywords

fulldf['keywords'][0]

“[‘culture clash’, ‘future’, ‘space war’, ‘space colony’, ‘society’, ‘space travel’, ‘futuristic’, ‘romance’, ‘space’, ‘alien’, ‘tribe’, ‘alien planet’, ‘cgi’, ‘marine’, ‘soldier’, ‘battle’, ‘love affair’, ‘anti war’, ‘power relations’, ‘mind and soul’, ‘3d’]”

#change keywords to type list
fulldf['keywords']=fulldf['keywords'].str.strip('[]').str.replace(' ','').str.replace("'",'').str.replace('"','')
fulldf['keywords']=fulldf['keywords'].str.split(',')
for i,j in zip(fulldf['keywords'],fulldf.index):
    list2=[]
    list2 = i
    list2.sort()
    fulldf.loc[j,'keywords']=str(list2)
fulldf['keywords'][0]

“[‘3d’, ‘alien’, ‘alienplanet’, ‘antiwar’, ‘battle’, ‘cgi’, ‘cultureclash’, ‘future’, ‘futuristic’, ‘loveaffair’, ‘marine’, ‘mindandsoul’, ‘powerrelations’, ‘romance’, ‘society’, ‘soldier’, ‘space’, ‘spacecolony’, ‘spacetravel’, ‘spacewar’, ‘tribe’]”

fulldf['keywords']=fulldf['keywords'].str.strip('[]').str.replace(' ','').str.replace("'",'').str.replace('"','')
fulldf['keywords']=fulldf['keywords'].str.split(',')
words_list = []
for index, row in fulldf.iterrows():genres = row["keywords"]for genre in genres:if genre not in words_list:words_list.append(genre)
len(words_list)

9772

def binary(words):binaryList = []for genre in words_list:if genre in words:binaryList.append(1)else:binaryList.append(0)return binaryList
fulldf['words_vec'] = fulldf['keywords'].apply(lambda x: binary(x))

recommend model

取余弦值作为相似性度量,根据选取的特征向量计算影片间的相似性;计算距离最近的前10部影片作为推荐

fulldf=fulldf[(fulldf['vote_average']!=0)] #removing the fulldf with 0 score and without drector names
fulldf=fulldf[fulldf['director']!='']
from scipy import spatialdef Similarity(movieId1, movieId2):a = fulldf.iloc[movieId1]b = fulldf.iloc[movieId2]genresA = a['genre_vec']genresB = b['genre_vec']genreDistance = spatial.distance.cosine(genresA, genresB)castA = a['cast_vec']castB = b['cast_vec']castDistance = spatial.distance.cosine(castA, castB)directA = a['director_vec']directB = b['director_vec']directDistance = spatial.distance.cosine(directA, directB)wordsA = a['words_vec']wordsB = b['words_vec']wordsDistance = spatial.distance.cosine(directA, directB)return genreDistance + directDistance + castDistance + wordsDistance
Similarity(3,160)

2.7958758547680684

columns =['original_title','genres','vote_average','genre_vec','cast_vec','director','director_vec','words_vec']
tmp = fulldf.copy()
tmp =tmp[columns]
tmp['id'] = list(range(0,fulldf.shape[0]))
tmp.head()
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

original_title genres vote_average genre_vec cast_vec director director_vec words_vec id
0 Avatar [Action, Adventure, Fantasy, ScienceFiction] 7.2 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … James Cameron [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, … 0
1 Pirates of the Caribbean: At World’s End [Adventure, Fantasy, Action] 6.9 [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, … Gore Verbinski [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … 1
2 Spectre [Action, Adventure, Crime] 6.3 [1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, … Sam Mendes [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … 2
3 The Dark Knight Rises [Action, Crime, Drama, Thriller] 7.6 [1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, … Christopher Nolan [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … 3
4 John Carter [Action, Adventure, ScienceFiction] 6.1 [1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … Andrew Stanton [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … 4
tmp.isnull().sum()

original_title 0
genres 0
vote_average 0
genre_vec 0
cast_vec 0
director 0
director_vec 0
words_vec 0
id 0
dtype: int64

import operator
def recommend(name):film=tmp[tmp['original_title'].str.contains(name)].iloc[0].to_frame().Tprint('Selected Movie: ',film.original_title.values[0])def getNeighbors(baseMovie):distances = []for index, movie in tmp.iterrows():if movie['id'] != baseMovie['id'].values[0]:dist = Similarity(baseMovie['id'].values[0], movie['id'])distances.append((movie['id'], dist))distances.sort(key=operator.itemgetter(1))neighbors = []for x in range(10):neighbors.append(distances[x])return neighborsneighbors = getNeighbors(film)print('\nRecommended Movies: \n')for nei in neighbors:  print( tmp.iloc[nei[0]][0]+" | Genres: "+str(tmp.iloc[nei[0]][1]).strip('[]').replace(' ','')+" | Rating: "+str(tmp.iloc[nei[0]][2]))print('\n')
recommend('Godfather')

Selected Movie: The Godfather: Part III

Recommended Movies:

The Godfather: Part II | Genres: 'Drama','Crime' | Rating: 8.3
The Godfather | Genres: 'Drama','Crime' | Rating: 8.4
The Rainmaker | Genres: 'Drama','Crime','Thriller' | Rating: 6.7
The Outsiders | Genres: 'Crime','Drama' | Rating: 6.9
The Conversation | Genres: 'Crime','Drama','Mystery' | Rating: 7.5
The Cotton Club | Genres: 'Music','Drama','Crime','Romance' | Rating: 6.6
Apocalypse Now | Genres: 'Drama','War' | Rating: 8.0
Twixt | Genres: 'Horror','Thriller' | Rating: 5.0
New York Stories | Genres: 'Comedy','Drama','Romance' | Rating: 6.2
Peggy Sue Got Married | Genres: 'Comedy','Drama','Fantasy','Romance' | Rating: 5.9

相关函数解释

json格式处理

json是一种数据交换格式,以键值对的形式呈现,支持任何类型
- json.loads用于解码json格式,将其转为dict;
- 其逆操作,即转为json格式,是json.dumps(),若要存储为json文件,需要先dumps转换再写入
- json.dump()用于将dict类型的数据转成str,并写入到json文件中,json.dump(json,file)
- json.load()用于从json文件中读取数据。json.load(file)

exam = {'a':'1111','b':'2222','c':'3333','d':'4444'}
file = 'exam.json'
jsobj = json.dumps(exam)
# solution 1
with open(file,'w') as f:f.write(jsobj)f.close()
#solution 2
json.dump(exam,open(file,'w'))

zip()操作

  • zip()操作:用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
  • 其逆操作为*zip(),举例如下:
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b)
for i in zipped:print(i)
print('\n')
shor_z = zip(a,c)
for j in shor_z:#取最短print(j)

(1, 4) (2, 5) (3, 6) (1, 4) (2, 5) (3, 6)

z=list(zip(a,b))
z

[(1, 4), (2, 5), (3, 6)]

list(zip(*z))#转为list能看见

[(1, 2, 3), (4, 5, 6)]

pandas merge/rename

pd.merge()通过键合并

a=pd.DataFrame({'lkey':['foo','foo','bar','bar'],'value':[1,2,3,4]})
a
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

lkey value
0 foo 1
1 foo 2
2 bar 3
3 bar 4
for index,row in a.iterrows():print(index)print('*****')print(row)

0 ***** lkey foo value 1 Name: 0, dtype: object 1 ***** lkey foo value 2 Name: 1, dtype: object 2 ***** lkey bar value 3 Name: 2, dtype: object 3 ***** lkey bar value 4 Name: 3, dtype: object

b=pd.DataFrame({'rkey':['foo','foo','bar','bar'],'value':[5,6,7,8]})
b
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

rkey value
0 foo 5
1 foo 6
2 bar 7
3 bar 8
pd.merge(a,b,left_on='lkey',right_on='rkey',how='left')
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

lkey value_x rkey value_y
0 foo 1 foo 5
1 foo 1 foo 6
2 foo 2 foo 5
3 foo 2 foo 6
4 bar 3 bar 7
5 bar 3 bar 8
6 bar 4 bar 7
7 bar 4 bar 8
pd.merge(a,b,left_on='lkey',right_on='rkey',how='inner')
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

lkey value_x rkey value_y
0 foo 1 foo 5
1 foo 1 foo 6
2 foo 2 foo 5
3 foo 2 foo 6
4 bar 3 bar 7
5 bar 3 bar 8
6 bar 4 bar 7
7 bar 4 bar 8

pd.rename()对行列重命名

dframe= pd.DataFrame(np.arange(12).reshape((3, 4)),index=['NY', 'LA', 'SF'],columns=['A', 'B', 'C', 'D'])
dframe
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

A B C D
NY 0 1 2 3
LA 4 5 6 7
SF 8 9 10 11
dframe.rename(columns={'A':'alpha'})
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

alpha B C D
NY 0 1 2 3
LA 4 5 6 7
SF 8 9 10 11
dframe
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

A B C D
NY 0 1 2 3
LA 4 5 6 7
SF 8 9 10 11
dframe.rename(columns={'A':'alpha'},inplace=True)
dframe
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }

alpha B C D
NY 0 1 2 3
LA 4 5 6 7
SF 8 9 10 11

pandas datetime格式

pandas to_datetime()转为datetime格式

Wordcloud

wordcloud词云模块:
1.安装:在conda cmd中输入conda install -c conda-forge wordcloud
2.步骤:读入背景图片,文本,实例化Wordcloud对象wc,
wc.generate(text)产生云图,plt.imshow()显示图片参数:
mask:遮罩图,字的大小布局和颜色都会依据遮罩图生成
background_color:背景色,默认黑
max_font_size:最大字号

nltk简单介绍

from nltk.corpus import stopwords
如果stopwords报错没有安装,可以在anaconda cmd中import nltk;nltk.download()
在弹出窗口中选择corpa,stopword,刷新并下载
同理,在models选项卡中选择Punkt Tokenizer Model刷新并下载,可安装nltk.word_tokenize()分词:
nltk.sent_tokenize(text) #对文本按照句子进行分割

nltk.word_tokenize(sent) #对句子进行分词

stopwords:个人理解是对表述不构成影响,大量存在,且可以直接过滤掉的词

参考文章:

what’s my score
TMDB means per genre


新手学习,欢迎指教!

kaggle TMDB5000电影数据分析和电影推荐模型相关推荐

  1. python电影数据分析的代码_python-small-examples

    Kaggle电影数据分析实战 本项目基于Kaggle电影影评数据集,通过这个系列,你将学到如何进行数据探索性分析(EDA),学会使用数据分析利器pandas,会用绘图包pyecharts,以及EDA时 ...

  2. 初识sparklyr—电影数据分析

    这篇文章是初次使用sparklyr扩展包来进行一些数据分析,对Spark牵扯不是很多.使用的数据是movieLens 100k,这份数据包含943个用户对1680部电影的评分数据,如需获取数据请在文末 ...

  3. 电影推荐系统(数据预处理+模型训练+预测)

    博客源地址 电影推荐思路   利用doc2vec做电影推荐,其实核心就是比较两部电影介绍文本之间的向量相似程度.自然语言处理中的分布式假设提出了"某个单词的含义由它周围的单词形成" ...

  4. 【大数据基础】基于 TMDB 数据集的电影数据分析

    https://dblab.xmu.edu.cn/blog/2400/ 实验内容 环境搭建 pip3 install bottle 数据预处理 本次项目使用的数据集来自知名数据网站 Kaggle 的 ...

  5. 电影数据分析需求文档

    电影数据分析需求文档 1.项目概述 1.1项目背景 1.2项目目的 1.3产品简介 2.项目总体设计 2.1可行性分析 2.2项目要解决的问题 2.3项目目标 3.功能需求 3.1功能划分 3.2功能 ...

  6. python电影数据分析报告_Python数据分析实战:TMDB电影数据可视化

    一.数据预处理 本文将以项目实战的形式,对 TMDB电影数据进行数据分析与可视化实战,所使用的数据来源于 Kaggle,文末提供数据的下载方式. import json import pandas a ...

  7. 大数据项目开发案例_大数据分析技术——项目案例1(猫眼电影数据分析上)...

    壹 猫眼Top100电影数据分析概述 从这一节开始,我们就综合利用已学到的一些分析技术来尝试做一些比较复杂的实际数据分析项目.在这些实际的项目案例中,我们将会看到一个完整的数据分析流程:数据清理--数 ...

  8. 电影动漫视频推荐网站

    1 简介 今天向大家介绍一个帮助往届学生完成的毕业设计项目,电影动漫视频推荐网站. 计算机毕业生设计,课程设计需要帮助的可以找我 2 设计概要 21世纪是信息化时代,随着信息技术和网络技术的发展,信息 ...

  9. 电影数据分析——国产烂片深度揭秘

    1 读取数据,以"豆瓣评分"为标准,看看电影评分分布,及烂片情况 要求: ① 读取数据"moviedata.xlsx",去除缺失值 ② 查看"豆瓣评分 ...

  10. Rotten Tomatoes 电影数据分析

    "烂番茄"电影数据分析 "烂番茄"电影数据分析 背景 数据采集及处理 数据可视化 得出结论 背景 一千个读者眼中有一千个哈姆雷特, 看电影也是一种艺术鉴赏活动, ...

最新文章

  1. C++中sprintf()函数的使用详解
  2. 中法计算机专业,计算机专业中法对照词汇
  3. 7 centos 源码安装samba_Centos-7安装zabbix
  4. 双系统格盘后因grub无法进入xp系统问题,将linux所在分区格后启动停在grub。。。无法进入系统
  5. 集成开发环境IDE的概述
  6. 看我如何拿下公司OA服务器
  7. Java开发十大常用网站
  8. 云计算实战系列十四(MySQL基础)
  9. 8086 按开关灯亮 c语言程序,基于MCS-51的交通灯程序设计(c语言控制直行左转)...
  10. Golang学习 - sync 包
  11. 巧为Win10家庭版开启组策略编辑器功能
  12. 利用监听器实现在线人数统计
  13. 应用安全-Web安全-越权漏洞整理
  14. ajax上传文件时显示进度
  15. 计算机设置鼠标关灯,老司机详解罗技鼠标怎样关闭灯光
  16. C#中SqlParameter的作用与用法
  17. iOS系统字体大全,iOS系统中所有的字体
  18. 在宝塔部署出现require(): open_basedir restriction in effect. File解决办法
  19. TASK SCHEDULE(任务计划)服务无法运行 解决方案
  20. 高效能人士的七个习惯 与成功有约

热门文章

  1. 调色盘——将真彩色图像降级为低分辨率图像的八叉树算法
  2. 两代 2011/2014 Mac Mini 硬盘SSD性能提升研究。(SSD固态硬盘研究)
  3. 1.42 财务测量指标——静态评价法(投资回报率+投资回收期)
  4. oracle 加载dbf文件路径,Oracle 导入DBF故障存储文件
  5. python定义一个矩形类_矩形类Python
  6. PV、UV、IV的概念
  7. 微分算子法解微分方程
  8. 三角函数π/2转化_分析最简单的正弦和余弦三角函数的图像
  9. MATLAB机器人工具箱2-机器人模型建立
  10. 通过Python实现九九乘法表