Perform EDA on Movie csv

Perform EDA on Movie csv

Create a CSV file named movies.csv with the following attributes: (Movie ID, Title, Genre, Rating, BoxOfficeCollection, Year). Store at least 20 records. Perform EDA

# ============================================
# Q1. Movie Data Analysis - EDA
# ============================================

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

# ============================================
# Part 1: Create CSV file with Indian Movies
# ============================================

# Creating dataset of Indian movies (Bollywood, Tollywood, etc.)
movies_data = {
'Movie ID': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
'Title': ['Jawan', 'Pathaan', 'Gadar 2', 'Animal', 'KGF 2',
'RRR', 'Pushpa', 'Bahubali 2', 'Dangal', 'PK',
'3 Idiots', 'Gully Boy', 'Andhadhun', 'Uri', 'War',
'Tiger Zinda Hai', 'Padmaavat', 'Sanju', 'Sultan', 'Dhoom 3'],
'Genre': ['Action', 'Action', 'Action', 'Crime', 'Action',
'Action', 'Action', 'Action', 'Drama', 'Comedy',
'Comedy', 'Drama', 'Thriller', 'Action', 'Action',
'Action', 'Drama', 'Biopic', 'Sports', 'Action'],
'Rating': [8.1, 7.5, 7.9, 8.6, 8.5,
8.9, 7.8, 9.0, 8.7, 8.2,
8.4, 8.0, 8.3, 8.5, 8.6,
7.3, 7.8, 7.9, 8.2, 7.5],
'BoxOfficeCollection': [640, 550, 520, 490, 460,
430, 390, 360, 330, 300,
280, 260, 240, 220, 200,
190, 180, 170, 160, 150],
'Year': [2023, 2023, 2023, 2023, 2022,
2022, 2021, 2017, 2016, 2014,
2009, 2019, 2018, 2019, 2019,
2017, 2018, 2018, 2016, 2013]
}

# Convert to DataFrame
df_movies = pd.DataFrame(movies_data)

# Save to CSV
df_movies.to_csv('movies.csv', index=False)
print("movies.csv created successfully!\n")

# ============================================
# Part 2: Load dataset
# ============================================

df = pd.read_csv('movies.csv')
print("="*60)
print("PART 2: Dataset Loaded Successfully")
print("="*60)

# ============================================
# Part 3: Display top 5 movies
# ============================================

print("\n" + "="*60)
print("PART 3: Top 5 Movies")
print("="*60)
print(df.head())

# ============================================
# Part 4: Univariate Analysis on Rating
# ============================================

print("\n" + "="*60)
print("PART 4: Univariate Analysis on Rating")
print("="*60)

# Descriptive statistics
print("\n Descriptive Statistics for Rating:")
print(df['Rating'].describe())

# Additional statistics
print(f"\n Mode of Rating: {df['Rating'].mode().values[0]}")
print(f" Variance of Rating: {df['Rating'].var():.3f}")
print(f" Standard Deviation: {df['Rating'].std():.3f}")
print(f" Skewness: {df['Rating'].skew():.3f}")
print(f" Kurtosis: {df['Rating'].kurtosis():.3f}")

# Count of movies by rating range
rating_bins = [7.0, 7.5, 8.0, 8.5, 9.0, 9.5]
rating_labels = ['7.0-7.5', '7.5-8.0', '8.0-8.5', '8.5-9.0', '9.0-9.5']
df['Rating_Range'] = pd.cut(df['Rating'], bins=rating_bins, labels=rating_labels, right=False)
print("\n Distribution by Rating Range:")
print(df['Rating_Range'].value_counts().sort_index())

# Visualization - Histogram
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.hist(df['Rating'], bins=8, color='skyblue', edgecolor='black', alpha=0.7)
plt.xlabel('Rating')
plt.ylabel('Frequency')
plt.title('Distribution of Movie Ratings')
plt.axvline(df['Rating'].mean(), color='red', linestyle='dashed', linewidth=2, label=f'Mean: {df["Rating"].mean():.2f}')
plt.axvline(df['Rating'].median(), color='green', linestyle='dashed', linewidth=2, label=f'Median: {df["Rating"].median():.2f}')
plt.legend()

# Box plot
plt.subplot(1, 2, 2)
plt.boxplot(df['Rating'], vert=True)
plt.ylabel('Rating')
plt.title('Box Plot of Movie Ratings')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# ============================================
# Part 5: Bivariate Analysis between Year and BoxOfficeCollection
# ============================================

print("\n" + "="*60)
print("PART 5: Bivariate Analysis - Year vs BoxOfficeCollection")
print("="*60)

# Group by Year to see trend
yearly_collection = df.groupby('Year')['BoxOfficeCollection'].agg(['sum', 'mean', 'count']).sort_index()
print("\nšŸ“Š Year-wise Box Office Collection:")
print(yearly_collection)

# Scatter plot with regression line
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.scatter(df['Year'], df['BoxOfficeCollection'], alpha=0.6, s=100, color='coral')
plt.xlabel('Year')
plt.ylabel('Box Office Collection (in Crores ₹)')
plt.title('Year vs Box Office Collection')
plt.grid(True, alpha=0.3)

# Add trend line
z = np.polyfit(df['Year'], df['BoxOfficeCollection'], 1)
p = np.poly1d(z)
plt.plot(df['Year'].sort_values(), p(df['Year'].sort_values()), "r--", linewidth=2, label='Trend Line')
plt.legend()

# Bar plot - Average collection by year
plt.subplot(1, 2, 2)
yearly_avg = df.groupby('Year')['BoxOfficeCollection'].mean().sort_index()
plt.bar(yearly_avg.index.astype(str), yearly_avg.values, color='lightgreen', edgecolor='black')
plt.xlabel('Year')
plt.ylabel('Average Collection (in Crores ₹)')
plt.title('Average Box Office Collection by Year')
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3, axis='y')

plt.tight_layout()
plt.show()

# Correlation between Year and BoxOfficeCollection
correlation_year = df['Year'].corr(df['BoxOfficeCollection'])
print(f"\n Correlation between Year and BoxOfficeCollection: {correlation_year:.3f}")

# ============================================
# Part 6: Multivariate correlation matrix
# ============================================

print("\n" + "="*60)
print("PART 6: Multivariate Correlation Matrix")
print("="*60)

# Select numerical columns for correlation
numerical_cols = ['Movie ID', 'Rating', 'BoxOfficeCollection', 'Year']
correlation_matrix = df[numerical_cols].corr()

print("\n Correlation Matrix:")
print(correlation_matrix)

# Heatmap visualization
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.3f',
linewidths=0.5, square=True, cbar_kws={"shrink": 0.8})
plt.title('Correlation Matrix of Movie Features')
plt.show()

# ============================================
# Part 7: Detect and handle missing values
# ============================================

print("\n" + "="*60)
print("PART 7: Detect and Handle Missing Values")
print("="*60)

# Check for missing values
print("\n Missing Values Count:")
print(df.isnull().sum())

# Check percentage of missing values
print("\n Percentage of Missing Values:")
print((df.isnull().sum() / len(df)) * 100)

# Create a copy with some missing values for demonstration
df_with_missing = df.copy()

# Insert some missing values (for demonstration)
# In real scenario, these would already be present
df_with_missing.loc[0, 'Rating'] = np.nan # Add missing rating for movie 1
df_with_missing.loc[2, 'BoxOfficeCollection'] = np.nan # Add missing box office for movie 3

print("\n After Inserting Missing Values (Demo):")
print(df_with_missing.head())

# Handling missing values - Method 1: Drop rows with missing values
df_dropped = df_with_missing.dropna()
print(f"\n After dropping rows with missing values: {len(df_dropped)} rows remaining")

# Handling missing values - Method 2: Fill with mean (for numerical columns)
df_filled = df_with_missing.copy()
df_filled['Rating'] = df_filled['Rating'].fillna(df_filled['Rating'].mean())
df_filled['BoxOfficeCollection'] = df_filled['BoxOfficeCollection'].fillna(df_filled['BoxOfficeCollection'].mean())

print("\n After filling missing values with mean:")
print(df_filled.head())

# Handling missing values - Method 3: Fill with median
df_median_filled = df_with_missing.copy()
df_median_filled['Rating'] = df_median_filled['Rating'].fillna(df_median_filled['Rating'].median())
df_median_filled['BoxOfficeCollection'] = df_median_filled['BoxOfficeCollection'].fillna(df_median_filled['BoxOfficeCollection'].median())

print("\nšŸ“Š After filling missing values with median:")
print(df_median_filled.head())

# ============================================
# Additional EDA - Genre Analysis
# ============================================

print("\n" + "="*60)
print("Additional Analysis: Genre Insights")
print("="*60)

# Count movies by genre
print("\n Movie Count by Genre:")
print(df['Genre'].value_counts())

# Average rating by genre
print("\n Average Rating by Genre:")
print(df.groupby('Genre')['Rating'].mean().sort_values(ascending=False))

# Average box office collection by genre
print("\n Average Box Office Collection by Genre:")
print(df.groupby('Genre')['BoxOfficeCollection'].mean().sort_values(ascending=False))

# Visualization - Genre Analysis
plt.figure(figsize=(15, 5))

# Subplot 1: Genre distribution
plt.subplot(1, 3, 1)
genre_counts = df['Genre'].value_counts()
plt.pie(genre_counts.values, labels=genre_counts.index, autopct='%1.1f%%', startangle=90)
plt.title('Distribution of Movies by Genre')

# Subplot 2: Average rating by genre
plt.subplot(1, 3, 2)
avg_rating_by_genre = df.groupby('Genre')['Rating'].mean().sort_values()
plt.barh(avg_rating_by_genre.index, avg_rating_by_genre.values, color='lightcoral')
plt.xlabel('Average Rating')
plt.title('Average Rating by Genre')
plt.xlim(7, 10)

# Subplot 3: Average collection by genre
plt.subplot(1, 3, 3)
avg_collection_by_genre = df.groupby('Genre')['BoxOfficeCollection'].mean().sort_values()
plt.barh(avg_collection_by_genre.index, avg_collection_by_genre.values, color='lightblue')
plt.xlabel('Average Collection (in Crores ₹)')
plt.title('Average Collection by Genre')

plt.tight_layout()
plt.show()

print("\n EDA Completed Successfully!")