# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Data Import and First Inspection

# Importing the dependencies

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# Setting Pandas

# +
# Shot up to 30 columns
pd.options.display.max_columns = 30

# Float with just two decimal places
pd.options.display.float_format = '{:,.2f}'.format
# -

# Reading the dataset

# importing the dataset, forcing tha pandas
# to treate the data on column 'release_date'
# as date format
df = pd.read_csv('movies_complete.csv',
                 parse_dates = ['release_date'])

df

df.info()

df.columns.tolist()

df.budget_musd.value_counts()

df.describe()

df.hist(figsize=(20,12),bins=100)
plt.show()

# # The Best and the Worst Movie

from IPython.display import HTML

# +
df_best = df[['poster_path',
           'title',
           'budget_musd',
           'revenue_musd',
           'vote_count',
           'vote_average',
           'popularity',
           'release_date']].copy()


# profits is the difference between revenue and budget
#df['profit_musd'] = df.revenue_musd.sub(df.budget_musd)
df_best['profit_musd'] = df_best['revenue_musd']-df_best['budget_musd']

# return precentual
df_best['return'] = df_best['revenue_musd']/df_best['budget_musd']

# Changing the names of columns
df_best.columns = ['',
                   'Title',
                   'Budget',
                   'Revenue',
                   'Votes',
                   'Average Rating',
                   'Popularity',
                   'Date',
                   'Profit',
                   'ROI' ]

# Changind the index
df_best.set_index('Title',inplace = True)

# Filling non numerical values with 0
#for column in ['Budget','Average Rating','Revenue']:
#    df_best[column].fillna(0,inplace = True)
# -

df_best.info()


# +
def checking_intervals(df_best,intervals = []):
    
    range_list = []
    
    if len(intervals) > 0:
        f_type = type(min)
        df_inter = pd.DataFrame(intervals)
        for col in df_best.columns.tolist()[1:]:

            clmn = df_inter.loc[df_inter[0] == col]

            min_list = clmn[1].tolist()
            max_list = clmn[2].tolist()

            minValue = None
            maxValue = None

            while min in min_list: min_list.remove(min)
            if len(min_list) == 0:
                minValue = min
                min_list = [min]

            while max in min_list: min_list.remove(max)
            if len(min_list) == 0: minValue = max

            while max in max_list: max_list.remove(max)
            if len(max_list) == 0:
                maxValue = max
                max_list = [max]

            while min in max_list: max_list.remove(min)
            if len(max_list) == 0: maxValue = min

            if minValue == None: minValue = max(min_list)
            if maxValue == None: maxValue = min(max_list)

            if(minValue == max or maxValue == min):
                range_list.append([col,maxValue,minValue])

            else:
                range_list.append([col,minValue,maxValue])

        
    return range_list


def filtering_movies(df_best,conditional_array):
    df_best_cpy = df_best.copy()
    df_Interval = df_best_cpy.describe().loc[['min','max']]
        
    try: 
        for cond in conditional_array: 
            column,minValue,maxValue = cond
            if not (minValue == min):  df_Interval[column]['min'] = minValue
            if not (maxValue == max): df_Interval[column]['max'] = maxValue
    except:
        print('>>> Error on conditions.')

    df_best_cpy = df_best.copy()
    conditions  = True
    for column in df_Interval.columns.tolist():
        conditions  &= df_best_cpy[column] >= df_Interval[column]['min']
        conditions  &= df_best_cpy[column] <= df_Interval[column]['max']
        
    return df_best_cpy[conditions]


def classification(df_best,by,intervals=[],quantiles=[],ascending=False):
    '''
    Its possible to use this function with the original dataframe to
    
    '''
    listQuant = []
    
    for elem in quantiles:
        col,minQ,maxQ = elem
        non_null = df_best[df_best[col] != 0][col].dropna()
        if( (0 <= minQ <= 1.) & (0 <= maxQ <= 1.) ):
            listQuant.append([col,non_null.quantile(minQ),non_null.quantile(maxQ)])
            
        
    return filtering_movies(df_best,
                            checking_intervals(df_best,intervals = intervals+listQuant)).sort_values(by=by,ascending=ascending)

def best_worst(df_best,by,n=5,intervals=[],ascending=False,quantiles=[]):
    dataframe = classification(df_best,by=by,intervals=intervals,quantiles=quantiles,ascending=ascending)
    subset = dataframe[['',by]]
    return HTML(subset.iloc[:n].to_html(escape=False))
    
    
# -

MoviesList = classification(df_best,by=['Average Rating','Date'],
                            intervals=[['Budget',min,max],
                                       ['Revenue',min,max],
                                       ['Votes',1000,max],
                                       ['Average Rating',min,max],
                                       ['Popularity',min,60],
                                       #['Date',datetime.datetime(2000, 1, 1),datetime.datetime(2000, 1, 1)],
                                       ['Profit',min,max],
                                       ['ROI',min,max]
                                      ],
                           
                           quantiles =[#['Budget',0.02275, 0.97725],
                                       #['Revenue',0.02275, 0.97725],
                                       ['Votes',0.02275, 1.0],
                                       ['Average Rating',0.7, 1.0],
                                       #['Popularity',0.00,1.],
                                       #['Date',0,1],
                                       #['Profit',0.02275, 0.97725],
                                       #['ROI',0.025, 0.975]
                                      ]
                           )
MoviesList.plot.scatter(x='Budget',y='Popularity')

MoviesList = classification(df_best,by=['Average Rating','Date'],
                            intervals=[['Budget',min,max],
                                       ['Revenue',min,max],
                                       ['Votes',1000,max],
                                       ['Average Rating',min,max],
                                       ['Popularity',min,max],
                                       #['Date',datetime.datetime(2000, 1, 1),datetime.datetime(2000, 1, 1)],
                                       ['Profit',min,max],
                                       ['ROI',min,max]
                                      ],
                           
                           quantiles = [#['Budget',0.02275, 0.97725],
                                       #['Revenue',0.02275, 0.97725],
                                       #['Votes',0.02275, 1.0],
                                       #['Average Rating',0.7, 1.0],
                                       #['Popularity',0.00,1.],
                                       #['Date',0,1],
                                       #['Profit',0.02275, 0.97725],
                                       #['ROI',0.025, 0.975]
                                      ]
                           )
MoviesList

MoviesList = classification(df_best,by='ROI',
                            intervals=[['Budget',5,max]]
                           )
MoviesList[:5]



# ## Movies Top 5 - Revenue

best_worst(df_best,'Revenue')

# ## Movies Top 5 - Highest Budget

best_worst(df_best,'Budget')

# ## Movies Top 5 - Highest Profit

best_worst(df_best,'Profit')

# ## Movies Top 5 - Lowest Profit

best_worst(df_best,'Profit',ascending=True)

# ## Movies Top 5 - Highest ROI

best_worst(df_best,by='ROI',intervals=[['Budget',50,max]])

# ## Movies Top 5 - Lowest ROI

best_worst(df_best,by='ROI',ascending=True,intervals=[['Budget',100,max]])

# ## Movies Top 5 - Highest Average Rating

best_worst(df_best,by='Average Rating',intervals=[['Votes',100,max]])

# ## Movies Top 5 - Lowest Average Rating

best_worst(df_best,by='Average Rating',ascending=True,intervals=[['Votes',500,max]])

# # Choosing a Movie

# +
df = pd.read_csv('movies_complete.csv',
                 parse_dates = ['release_date'])

df.columns = ['', 'Title', 'Tagline', 'Date', 'Genres',
       'Collection', 'Language', 'Budget',
       'Revenue', 'Companies', 'Countries',
       'Votes', 'Average Rating', 'Popularity', 'Runtime', 'Overview',
       'Spoken Languages', 'Poster', 'Cast', 'Cast Size', 'Crew Size',
       'Director']
# -

# ## Selecting movie by Genre

# +
conditions  = True
conditions &= df['Genres'].str.contains('Action')
conditions &= df['Genres'].str.contains('Science')

classification(df[conditions],by='Average Rating',intervals=[['Votes',100,max]]).iloc[:5]
# -

# ## Selecting by Actors

# +
conditions  = True
conditions &= df['Genres'].str.contains('Action')
conditions &= df['Genres'].str.contains('Science')
conditions &= df['Cast'].str.contains('Bruce Willis')

classification(df[conditions],by='Average Rating',intervals=[['Votes',min,max]]).iloc[:5]
# -

# ## Selecting by Actors and Genre

conditions  = True
conditions &= df['Cast'].str.contains('<NAME>')
conditions &= df['Cast'].str.contains('<NAME>')
classification(df[conditions],by='Average Rating',intervals=[['Votes',min,max]]).iloc[:5]

# ## Selecting by Actors and Director

conditions  = True
conditions &= df['Cast'].str.contains('Leonardo')
classification(df[conditions],by='Average Rating',intervals=[['Votes',min,max]]).iloc[:5]

# ## Simpler Way to Select Intervals

df.columns

conditions  = True
conditions &= df['Companies'].str.contains('Pixar')
conditions &= df['Date'].between('2010-01-01','2015-12-31')
classification(df[conditions],by='Average Rating',intervals=[['Votes',min,max]])

# +

classification(df[conditions],by='Average Rating',intervals=[['Votes',min,max]]).iloc[:5]
# -

# ## Action or Thriller Movie with original language English 

# +
conditions  = True
conditions &= df['Genres'].str.contains('Action') | df['Genres'].str.contains('Thriller')
conditions &= df['Language']=="en"
conditions &= df['Average Rating']>=7.5
conditions &= df['Votes']>=7.5

df[conditions].sort_values(by='Date',ascending=False)
# -

# ## Are franchises more sucessful?

# +
df['Franchise'] = df['Collection'].notna()

df_bud_interval = df[df['Budget'].notna()].copy()
# -

df['Franchise'].value_counts()

# ## Franchise x Stand-alone: Average Revenue

# +
franchise_mean_budget = df.groupby('Franchise')['Budget'].mean()[True]

# Choosing the budget interval of franchise movies
min_budget = df.groupby('Franchise')['Budget'].min()[True]
max_budget = df.groupby('Franchise')['Budget'].max()[True]
condition = df['Budget'].between(min_budget,max_budget)
df_budget = df[condition]
# -

# Couting the movies where min < budget < max
df_budget['Franchise'].value_counts()

# Grouping by Franchise
df_budget.groupby('Franchise')['Revenue'].mean()

# thats the same that evalute over original dataframe
# without na
df_bud_interval.groupby('Franchise')['Revenue'].mean()

# ## Franchise x Stand-alone: Return on Investiment

df['ROI'] = (df['Revenue'] / df['Budget'])
df_bud_interval['ROI'] = (df_bud_interval['Revenue'] / df_bud_interval['Budget'])

df.groupby('Franchise')['ROI'].median()

# na values doesnt change the median
df[df['ROI'].notna()].groupby('Franchise')['ROI'].median()

# ## Franchise x Stand-alone: Average Budget

df.groupby('Franchise')['Budget'].mean()

df.groupby('Franchise').agg('mean')

df_bud_interval.groupby('Franchise').agg({'Budget' :['sum','mean'],
                                          'Revenue':['sum','mean'],'Votes': 'mean','Average Rating':'mean'})

franchises = df.groupby('Collection').agg({'Title':'count',
                             'Budget' :['sum','mean'],
                             'Revenue':['sum','mean'],'Votes': 'mean','Average Rating':'mean'})

franchises.nlargest(20,('Title','count'))

franchises.nlargest(20,('Revenue','sum'))

franchises.nlargest(20,('Budget','sum'))

franchises.nlargest(20,('Revenue','mean'))

franchises[franchises[('Votes','mean')]>=1000].nlargest(20,('Average Rating','mean'))

# ## Most Successful Actors 

df.set_index('id',inplace=True)

df.info()

act = df['cast'].str.split('|',expand=True)

act = act.stack().reset_index(level=1,drop=True).to_frame()

act.columns = ['Actor']

act['Actor']

act = act.merge(df[['title','revenue_musd','vote_average','popularity']],how = 'left',left_index=True,right_index=True)

df[['title']]



StarcoderdataJupyterScriptsDedupFiltered