import pandas as pd import numpy as np from functools import lru_cache @lru_cache(maxsize=1) def load_movie_data(file_path="movie_metadata.parquet"): """ Loads and caches the movie metadata parquet file. Performs data cleaning, calculates the trending score, and creates standard fields. """ try: df = pd.read_parquet(file_path) except Exception as e: print(f"Error loading {file_path}: {e}") # Return a fallback empty DataFrame with correct columns if load fails df = pd.DataFrame(columns=["movie_id", "title", "year", "avg_rating", "rating_count"]) # Data cleaning: fill missing values df["year"] = df["year"].fillna(0).astype(int) df["avg_rating"] = df["avg_rating"].fillna(0.0).astype(float) df["rating_count"] = df["rating_count"].fillna(0).astype(int) df["title"] = df["title"].fillna("Unknown Title").astype(str) # Calculate trending score: (avg_rating * log(rating_count)) # Add a small epsilon to rating_count to prevent log(0) df["trending_score"] = df["avg_rating"] * np.log(df["rating_count"] + 1) return df def get_trending_movies(df, limit=20): """ Returns the top N movies sorted by trending score descending. """ return df.sort_values(by="trending_score", ascending=False).head(limit) def get_kpi_statistics(df): """ Calculates key metrics for the analytics dashboard: - Total Movies - Average Rating - Average Votes (Rating Count) - Most Popular Movie (Title & Count) - Newest Movie (Title & Year) """ if df.empty: return { "total_movies": 0, "avg_rating": 0.0, "avg_votes": 0, "most_popular": "N/A", "newest_movie": "N/A" } total_movies = len(df) avg_rating = float(df["avg_rating"].mean()) avg_votes = int(df["rating_count"].mean()) # Most popular movie (highest rating_count) pop_idx = df["rating_count"].idxmax() most_popular = f"{df.loc[pop_idx, 'title']} ({df.loc[pop_idx, 'rating_count']:,} votes)" # Newest movie (highest year, filtering out 0 years) valid_years_df = df[df["year"] > 0] if not valid_years_df.empty: new_idx = valid_years_df["year"].idxmax() newest_movie = f"{valid_years_df.loc[new_idx, 'title']} ({valid_years_df.loc[new_idx, 'year']})" else: newest_movie = "N/A" return { "total_movies": total_movies, "avg_rating": avg_rating, "avg_votes": avg_votes, "most_popular": most_popular, "newest_movie": newest_movie }