当前位置: 首页 > news >正文

寒假学习笔记2.8

一、实践练习:电影数据分析完整项目
项目目标
加载豆瓣电影Top250数据(昨天爬取的)

数据清洗与特征工程

多维度统计分析

可视化展示分析结果

生成分析报告

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

设置中文显示

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
sns.set_theme(style="whitegrid")

==================== 1. 数据加载 ====================

df = pd.read_csv('douban_top250.csv')
print("原始数据形状:", df.shape)
print("\n前5行:")
print(df.head())

==================== 2. 数据清洗 ====================

处理年份

df['year'] = df['year'].astype(str).str.extract('(\d+)').astype(float)

删除缺失年份的数据

df = df.dropna(subset=['year'])
df['year'] = df['year'].astype(int)

添加新特征

df['decade'] = (df['year'] // 10) * 10 # 年代
df['score_round'] = df['rating'].round(0) # 评分取整
df['score_category'] = pd.cut(df['rating'],
bins=[0, 7, 8, 9, 10],
labels=['一般', '良好', '优秀', '经典'])

添加评论长度特征

df['comment_length'] = df['comment'].fillna('').apply(len)
df['has_comment'] = df['comment'].notna()

print("\n清洗后数据信息:")
print(df.info())

==================== 3. 统计分析 ====================

print("\n=== 基本统计 ===")
print(df[['rating', 'year', 'comment_length']].describe())

按年代统计

decade_stats = df.groupby('decade').agg({
'title': 'count',
'rating': ['mean', 'max', 'min', 'std'],
'has_comment': 'sum'
}).round(2)
print("\n=== 按年代统计 ===")
print(decade_stats)

评分分布

score_dist = df['score_category'].value_counts().sort_index()
print("\n=== 评分等级分布 ===")
print(score_dist)

最老和最新的电影

oldest = df.nsmallest(3, 'year')[['title', 'year', 'rating']]
newest = df.nlargest(3, 'year')[['title', 'year', 'rating']]
print("\n=== 最老的三部电影 =")
print(oldest)
print("\n
= 最新的三部电影 ===")
print(newest)

==================== 4. 数据可视化 ====================

创建多子图画布

fig = plt.figure(figsize=(16, 12))

4.1 评分分布直方图

ax1 = fig.add_subplot(2, 3, 1)
sns.histplot(data=df, x='rating', bins=20, kde=True, ax=ax1)
ax1.set_title('豆瓣Top250评分分布')
ax1.set_xlabel('评分')
ax1.set_ylabel('电影数量')

4.2 不同年代电影数量

ax2 = fig.add_subplot(2, 3, 2)
decade_counts = df['decade'].value_counts().sort_index()
sns.barplot(x=decade_counts.index, y=decade_counts.values, ax=ax2, palette='viridis')
ax2.set_title('不同年代电影数量')
ax2.set_xlabel('年代')
ax2.set_ylabel('数量')
ax2.tick_params(axis='x', rotation=45)

4.3 年代与评分关系(箱线图)

ax3 = fig.add_subplot(2, 3, 3)
sns.boxplot(data=df, x='decade', y='rating', ax=ax3)
ax3.set_title('不同年代评分分布')
ax3.set_xlabel('年代')
ax3.set_ylabel('评分')
ax3.tick_params(axis='x', rotation=45)

4.4 评分与评论长度关系

ax4 = fig.add_subplot(2, 3, 4)
sns.scatterplot(data=df, x='rating', y='comment_length',
hue='score_category', alpha=0.6, ax=ax4)
ax4.set_title('评分与评论长度关系')
ax4.set_xlabel('评分')
ax4.set_ylabel('评论长度')

4.5 评分等级饼图

ax5 = fig.add_subplot(2, 3, 5)
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
df['score_category'].value_counts().plot.pie(
autopct='%1.1f%%', colors=colors, ax=ax5)
ax5.set_title('评分等级占比')
ax5.set_ylabel('')

4.6 评分最高的10部电影

ax6 = fig.add_subplot(2, 3, 6)
top10 = df.nlargest(10, 'rating')[['title', 'rating']]
sns.barplot(data=top10, y='title', x='rating',
palette='Reds_d', ax=ax6)
ax6.set_title('评分最高的10部电影')
ax6.set_xlabel('评分')
ax6.set_ylabel('')

plt.tight_layout()
plt.savefig('movie_analysis_full.png', dpi=300, bbox_inches='tight')
plt.show()

==================== 5. 高级分析 ====================

5.1 相关性矩阵

numeric_cols = df[['rating', 'year', 'comment_length']].copy()
corr_matrix = numeric_cols.corr()

plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm',
vmin=-1, vmax=1, center=0,
square=True, linewidths=1)
plt.title('变量相关性热力图')
plt.savefig('correlation_heatmap.png', dpi=300)
plt.show()

5.2 评分随年份变化的趋势

yearly_avg = df.groupby('year')['rating'].mean().reset_index()

plt.figure(figsize=(12, 6))
sns.regplot(data=yearly_avg, x='year', y='rating',
scatter_kws={'alpha':0.5, 's':50},
line_kws={'color':'red'})
plt.title('电影评分随年份变化趋势')
plt.xlabel('年份')
plt.ylabel('平均评分')
plt.grid(True, alpha=0.3)
plt.savefig('rating_trend.png', dpi=300)
plt.show()

5.3 联合分布图

g = sns.jointplot(data=df, x='year', y='rating', kind='hex', height=8)
g.fig.suptitle('年份与评分联合分布', y=1.02)
plt.savefig('joint_distribution.png', dpi=300)
plt.show()

==================== 6. 生成分析报告 ====================

with open('movie_analysis_report.txt', 'w', encoding='utf-8') as f:
f.write("=" * 50 + "\n")
f.write("豆瓣电影Top250数据分析报告\n")
f.write(f"生成时间:{pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write("=" * 50 + "\n\n")

f.write(f"数据总量:{len(df)} 部电影\n")
f.write(f"时间范围:{df['year'].min()}年 - {df['year'].max()}年\n")
f.write(f"平均评分:{df['rating'].mean():.2f}\n")
f.write(f"最高评分:{df['rating'].max()}({df.loc[df['rating'].idxmax(), 'title']})\n")
f.write(f"最低评分:{df['rating'].min()}({df.loc[df['rating'].idxmin(), 'title']})\n\n")f.write("评分等级分布:\n")
for cat, count in df['score_category'].value_counts().sort_index().items():f.write(f"  {cat}: {count}部 ({count/len(df)*100:.1f}%)\n")f.write("\n各年代电影数量:\n")
for decade, count in df['decade'].value_counts().sort_index().items():f.write(f"  {decade}年代: {count}部\n")

print("\n分析完成!报告已保存至 movie_analysis_report.txt")
二、遇到的问题与解决
问题:Pandas的groupby后数据结构混乱

解决:使用reset_index()将分组索引转回列,或使用as_index=False参数

问题:Seaborn中文显示乱码

解决:设置plt.rcParams['font.sans-serif']指定中文字体,如['SimHei']

问题:透视表聚合函数不生效

解决:检查数据类型,确保数值列是数字类型(pd.to_numeric()转换)

问题:时间序列重采样报错

解决:确保索引是DatetimeIndex类型,使用pd.to_datetime()转换

问题:Seaborn图表重叠

解决:使用plt.tight_layout()自动调整子图间距

三、学习总结
Pandas是数据分析的核心工具,掌握了分组聚合、透视表、时间序列等高级功能

Seaborn基于Matplotlib,提供了更高级的统计可视化接口,代码更简洁

数据分析的完整流程:数据采集→清洗→特征工程→分析→可视化→报告

数据可视化时,选择合适的图表类型比华丽的外观更重要

掌握了从原始数据到业务洞察的完整转化能力

http://www.jsqmd.com/news/390430/

相关文章:

  • 寒假学习笔记2.7
  • 树莓派pico播放玛丽有只小羊羔
  • AI原生应用:自然语言处理技术的10大核心应用场景解析
  • 树莓派pico蜂鸣器播放音乐
  • 树莓派 pico W(创客版)RP2020 W代码示例温度检测+液晶显示屏+HTTP服务器页面控制灯光
  • OpenClaw 产品定位
  • 钣金客户
  • 寒假学习笔记2.6
  • 寒假学习笔记2.5
  • 基于Spring Boot的酒店在线预订系统的开发与实现
  • day88(2.17)——leetcode面试经典150
  • 基于springboot企业员工信息管理系统_j57rz435
  • 基于SpringBoot的宠物寄领养网站的设计与实现_6fmr5z12
  • java毕业设计基于Spring Boot的危废料管理信息系统
  • 服务器运维(四十一)日服务器linux-audit.log分析工具—东方仙盟
  • 基于Spring Boot的戏曲平台的设计与实现
  • [嵌入式系统-240]:信号调理电路中的集成运放放大器的作用、种类、工作原理、示例
  • 成本治理(Cloud Cost Governance)是什么?
  • [嵌入式系统-239]:多路选择:模拟多路开关与数字多路开关
  • 信息论与编码篇---线性失真 vs 非线性失真
  • 信息论与编码篇---总谐波失真加噪声
  • LLM | 完全面向算法的 VeRL 代码阅读笔记
  • 魔兽世界伤害计算公式
  • 提示工程架构师请注意!Agentic AI对抗样本防御的10大核心技巧
  • 2026-02-17学习
  • 宇树科技 CEO 王兴兴所说的“具身智能时代的牛顿还没诞生”
  • 寒假学习笔记2.4
  • 存在即对话:方见华对话本体论与世毫九理论的数学奠基、形式证明与工程实现
  • 寒假学习笔记2.3
  • 摩尔线程快速完成对Qwen3.5模型全面适配