通过python对excel进行数据分析和可视化

cpp 复制代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

file_path = "C:\\Users\\86138\\Desktop\\book_list-计算机-机器学习-linux-android-数据库-互联网.xlsx"
data = pd.read_excel(file_path)

need_data = data[['书名', '评分', '评价人数']].copy()

#为 data_cleaned 数据框添加一个新列 书名字数,使用.str.len() 算字符串长度
need_data['书名字数'] = need_data['书名'].str.len()

#删除 data_cleaned 数据框中包含缺失值的行,使用 .dropna() 方法
need_data = need_data.dropna()
# 将评分列转换为数值类型,处理错误值
need_data['评分'] = pd.to_numeric(need_data['评分'], errors='coerce')
# 将评价人数列转换为数值类型,处理错误值
need_data['评价人数'] = pd.to_numeric(need_data['评价人数'], errors='coerce')
# 再次删除包含缺失值或无效值的行
need_data = need_data.dropna()

# sns.set() 函数设置绘图风格为 whitegrid(白色网格),调色板为 pastel(柔和色调),字体缩放比例为 1.2。
# 使用 plt.figure(figsize=(9, 7)) 创建一个大小为 (9, 7) 的图形,用于容纳后续的子图。
sns.set(style="whitegrid", palette="pastel", font_scale=1.2)
plt.figure(figsize=(9, 7))

# 创建第一个子图:
# plt.subplot(3, 1, 1) 创建一个 3 行 1 列的子图,并将子图设为第一个。
# 使用 sns.histplot() 绘制 评价人数 的直方图,bins=20 将数据划分为 20 个直方图区间,kde=True 添加核密度估计曲线
# 使用 plt.title() 为子图设标题,plt.xlabel() 和 plt.ylabel() 设置 x 轴和 y 轴的标签。
# 发现:评论计数的分布:大多数书籍的评论数量相对较少,但少数书籍的评论数量非常高
plt.subplot(3, 1, 1)
sns.histplot(need_data['评价人数'], bins=20, kde=True, color='skyblue')
plt.title('Rating with book counts')
plt.xlabel('Rating')
plt.ylabel('Book')

# 创建第二个子图
# 书名长度的分布:书名通常在5到15个字符之间,还有一些较长的字符
plt.subplot(3, 1, 2)
sns.histplot(need_data['书名字数'], bins=15, kde=True, color='lightgreen')
plt.title('Distribution of Book Title Lengths')
plt.xlabel('Number of Characters in Title')
plt.ylabel('Frequency')

# 第三个子图
# 评级分布:评级通常聚集在较高的范围内,介于8到10之间。
plt.subplot(3, 1, 3)
sns.histplot(need_data['评分'], bins=10, kde=True, color='salmon')
plt.title('Distribution of Ratings')
plt.xlabel('Ratings')
plt.ylabel('Frequency')

# 调整子图布局,使它们紧凑排列,避免重叠。
# 使用 plt.show() 显示绘制的图形
plt.tight_layout()
plt.show()

# 打印出 data 数据框的前几行,以便查看数据集的结构,使用 .head() 方法。
print("数据的前几行:")
print(data.head())

# 创建一个新的图形,大小为 15x10,用于绘制饼图和折线图
plt.figure(figsize=(15, 10))

# 将 评分 列的数据分成不同的分组(bins),范围是 0-6、6-7、7-8、8-9、9-10,使用 pd.cut() 函数,并为每个分组分配标签。
# 使用 value_counts(sort=False) 统计每个分组的数量。
rating_bins = pd.cut(need_data['评分'], bins=[0, 7,8, 9, 10], labels=['0 - 7','7 - 8', '8 - 9', '9 - 10'])
rating_counts = rating_bins.value_counts(sort=False)

# 创建一个 2 行 1 列的子图布局,并将当前子图设置为第一个。
# 使用 rating_counts.plot.pie() 绘制饼图,autopct='%1.1f%%' 表示在饼图上显示百分比,colors=sns.color_palette('pastel') 使用柔和色调,startangle=140 表示起始角度。
# 设置饼图的标题,并将 y 轴标签设为空,以提高美观度
plt.subplot(2, 1, 1)
rating_counts.plot.pie(autopct='%1.1f%%', colors=sns.color_palette('pastel'), startangle=140)
plt.title('Rating Counts')
plt.ylabel('')


plt.subplot(2, 1, 2)
sorted_data = need_data.sort_values(by='评分')
plt.plot(sorted_data['评分'], sorted_data['评价人数'], marker='o', color='teal', label='Review Counts')
plt.title('Single book review counts')
plt.xlabel('Book counts')
plt.ylabel('Reviewer counts')
plt.grid(alpha=0.3)
plt.legend()

# Adjust layout and show plots
plt.tight_layout()
plt.show()


#按 评分 列对 data_cleaned 数据框进行分组,使用 groupby('评分'),并计算每个组中 评价人数 的总和,结果存储在 total_reviews_by_rating 中。
total_reviews_by_rating = need_data.groupby('评分')['评价人数'].sum()

# Plot the total review counts across ratings
plt.figure(figsize=(10, 6))
plt.plot(total_reviews_by_rating.index, total_reviews_by_rating.values, marker='o', color='teal', label='Total Reviews')
plt.title('Sum count of reviewers', fontsize=16)
plt.xlabel('Book rating', fontsize=12)
plt.ylabel('Reviewer counts', fontsize=12)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()

整理后的代码

cpp 复制代码
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns


def load_and_preprocess_data(file_path):
    """
    加载并预处理数据
    :param file_path: Excel文件的路径
    :return: 预处理后的数据
    """
    data = pd.read_excel(file_path)
    # 提取所需数据列
    need_data = data[['书名', '评分', '评价人数']].copy()
    # 计算书名字数
    need_data['书名字数'] = need_data['书名'].str.len()
    # 去除缺失值和处理数据类型
    need_data = need_data.dropna(subset=['书名', '评分', '评价人数'])
    need_data['评分'] = pd.to_numeric(need_data['评分'], errors='coerce')
    need_data['评价人数'] = pd.to_numeric(need_data['评价人数'], errors='coerce')
    need_data = need_data.dropna(subset=['评分', '评价人数'])
    return need_data


def plot_histograms(need_data):
    """
    绘制直方图和核密度估计图
    :param need_data: 预处理后的数据
    """
    sns.set(style="whitegrid", palette="pastel", font_scale=1.2)
    fig, axs = plt.subplots(3, 1, figsize=(9, 7))
    # 评价人数的分布
    sns.histplot(need_data['评价人数'], bins=20, kde=True, color='skyblue', ax=axs[0])
    axs[0].set_title('Distribution of Review Counts')
    axs[0].set_xlabel('Review Counts')
    axs[0].set_ylabel('Frequency')
    # 书名字数的分布
    sns.histplot(need_data['书名字数'], bins=15, kde=True, color='lightgreen', ax=axs[1])
    axs[1].set_title('Distribution of Book Title Lengths')
    axs[1].set_xlabel('Number of Characters in Title')
    axs[1].set_ylabel('Frequency')
    # 评分的分布
    sns.histplot(need_data['评分'], bins=10, kde=True, color='salmon', ax=axs[2])
    axs[2].set_title('Distribution of Ratings')
    axs[2].set_xlabel('Ratings')
    axs[2].set_ylabel('Frequency')
    plt.tight_layout()
    plt.show()


def plot_pie_and_line_charts(need_data):
    """
    绘制饼图和折线图
    :param need_data: 预处理后的数据
    """
    plt.figure(figsize=(15, 20))
    # 分组统计评分分布
    rating_bins = pd.cut(need_data['评分'], bins=[0, 7, 8, 9, 10], labels=['0 - 7', '7 - 8', '8 - 9', '9 - 10'])
    rating_counts = rating_bins.value_counts(sort=False)
    # 饼图
    ax1 = plt.subplot(2, 1, 1)
    rating_counts.plot.pie(autopct='%1.1f%%', colors=sns.color_palette('pastel'), startangle=140)
    ax1.set_title('Rating Counts')
    ax1.set_ylabel('')
    # 折线图
    ax2 = plt.subplot(2, 1, 2)
    sorted_data = need_data.sort_values(by='评分')
    ax2.plot(sorted_data['评分'], sorted_data['评价人数'], marker='o', color='teal', label='Review Counts')
    ax2.set_title('Single book review counts')
    ax2.set_xlabel('Book counts')
    ax2.set_ylabel('Reviewer counts')
    ax2.grid(alpha=0.3)
    ax2.legend()
    plt.tight_layout()
    plt.show()


def plot_total_review_counts(need_data):
    """
    绘制总评论人数与评分的关系图
    :param need_data: 预处理后的数据
    """
    total_reviews_by_rating = need_data.groupby('评分')['评价人数'].sum()
    plt.figure(figsize=(10, 6))
    plt.plot(total_reviews_by_rating.index, total_reviews_by_rating.values, marker='o', color='teal', label='Total Reviews')
    plt.title('Sum count of reviewers', fontsize=16)
    plt.xlabel('Book rating', fontsize=12)
    plt.ylabel('Reviewer counts', fontsize=12)
    plt.grid(alpha=0.3)
    plt.legend()
    plt.tight_layout()
    plt.show()


if __name__ == "__main__":
    file_path = "C:\\Users\\86138\\Desktop\\book_list-计算机-机器学习-linux-android-数据库-互联网.xlsx"
    need_data = load_and_preprocess_data(file_path)
    print("数据的前几行:")
    print(need_data.head())
    plot_histograms(need_data)
    plot_pie_and_line_charts(need_data)
    plot_total_review_counts(need_data)
  1. 第一个子图( plt.subplot(3, 1, 1) ):
    • 图像类型:直方图和核密度估计图( sns.histplot )。
    • 分析关系:
      • 该图展示了 评价人数 的分布情况。
      • 横轴表示 评价人数,纵轴表示 频率。
      • 通过将 评价人数 数据划分为 20 bins 并绘制直方图,再加上核密度估计曲线,可以观察到书籍的评价人数的分布趋势。
      • 发现:可以看到大多数书籍的评价人数相对较少,但有少数书籍的评价人数非常高,呈现长尾分布,这意味着少数热门书籍吸引了大量的评价,而大部分书籍的评价相对较少。
  2. 第二个子图( plt.subplot(3, 1, 2) ):
    • 图像类型:直方图和核密度估计图( sns.histplot )。
    • 分析关系:
      • 该图展示了 书名字数 的分布情况。
      • 横轴表示 书名字数,即书名的字符长度,纵轴表示 频率。
      • 划分了 15 bins 并绘制直方图和核密度估计曲线。
      • 从图中可以观察到书名长度的分布规律,通常在 5 15 个字符之间,但也存在一些较长书名的书籍,能让用户了解书籍命名时书名长度的大致范围和分布情况。
  3. 第三个子图( plt.subplot(3, 1, 3) ):
    • 图像类型:直方图和核密度估计图( sns.histplot )。
    • 分析关系:
      • 该图展示了 评分 的分布情况。
      • 横轴表示 评分,纵轴表示 频率。
      • 划分了 10 bins 并绘制直方图和核密度估计曲线。
      • 可以看出书籍的 评分 通常聚集在较高的范围内,一般介于 8 10 之间,能让用户了解书籍评分的整体分布趋势,了解用户对书籍的总体评价倾向。

第二个 plt.figure 中的两个子图:

  1. 第一个子图( plt.subplot(2, 1, 1) ):
    • 图像类型:饼图( rating_counts.plot.pie )。
    • 分析关系:
      • 首先使用 pd.cut 评分 分成不同的范围: 0-6 6-7 7-8 8-9 9-10 ,并为这些范围分配了相应的标签。
      • 该饼图展示了不同评分范围的书籍在整个数据集中所占的比例。
      • 可以直观地看出不同评分范围的书籍的相对占比,使用 autopct='%1.1f%%' 显示每个扇形部分的百分比,帮助用户快速了解评分的分布结构。
  2. 第二个子图
    • 图像类型:折线图( plt.plot )。
    • 分析关系:
      • 首先对 data_cleaned 评分 进行排序( data_cleaned.sort_values(by=' 评分 ') )。
      • 该图展示了 评价人数 评分 的关系。
      • 横轴是 评分,纵轴是 评价人数,使用 marker='o' 标记每个数据点。
      • 可以看出不同评分的书籍对应的评价人数的趋势,可能反映出评分高低与评价人数多少之间的关系,例如评分高的书籍是否更受关注,评价人数更多。

第三个 plt.figure

  • 图像类型:折线图( plt.plot )。
  • 分析关系:
    • 首先对 data_cleaned 评分 分组并计算每个组中 评价人数 的总和( data_cleaned.groupby(' 评分 ')'** **评价人数** **'.sum() )。
    • 该图展示了不同评分下的总评价人数的关系。
    • 横轴是 Book rating ,纵轴是 Reviewer counts
    • 可以看出不同评分的书籍的总评价人数,例如可以发现哪个评分范围的书籍吸引了最多的总评价,帮助用户分析不同评分对评价人数总和的影响,以及不同评分书籍的受欢迎程度(从评价人数总和的角度)。
相关推荐
长和信泰光伏储能22 分钟前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂1 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study1 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境2 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境2 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1232 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102163 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb003 小时前
一个项目带你入门AI应用开发01
python
0566463 小时前
Python康复训练——常用标准库
开发语言·python·学习
昆曲之源_娄江河畔4 小时前
Python如何安装flask, pymssql
开发语言·python·flask·pymssql