豆瓣图书统计可视化分析

s此博客是建立于爬虫基础之上,首先我们需要对豆瓣网站的图书进行爬取,这里将不再展示爬取部分,直接进行数据清洗及可视化分析部分。


一.准备数据集

数据集在下方链接当中,如需请自取。

https://pan.baidu.com/s/146N5YQfE0hkkYm2JOZQsEg

豆瓣图书统计可视化分析_第1张图片


import pandas as pd
import numpy as np
import re
import openpyxl

df=pd.read_csv(r'book_douban.csv',index_col=0)
print(df.head(10)) #打印前十行进行观察

输出结果:

豆瓣图书统计可视化分析_第2张图片

 二.数据清洗

大概流程如下:

豆瓣图书统计可视化分析_第3张图片

 在该数据集当中,因为存在大量“不规则”字符,我们在使用的第一步就需要将该大类数据清洗,并且补全一些缺失项数据。这样在接下来的分析及可视化过程当中才可以顺利进行。

1.重新命名

因为原数据集当中的第六列的标题为:“数”很抽象,所以我们的第一步清洗就将“数”重命名为“页数”

df.rename(columns={'数':'页数'}, inplace=True)
df.reset_index(drop=True, inplace=True)
df.describe()
print(df.iloc[:, 4])

输出结果:

豆瓣图书统计可视化分析_第4张图片

观察可得,现在已经将“数”改为“页数”,接着我们将数据中的缺失值或空值删除或替换为其他值。

2.处理缺失值与空值

#将'none'转换为null
df = df.replace('None', np.nan)

#查看缺失值情况
print(df.isnull().sum())

#去除'ISBM'列
df = df.drop('ISBM', axis=1)

#去除指定列含有空值的行
df = df.dropna(subset=['作者','出版社','出版时间','页数','价格','评分','评论数量'], how='any')

#重置索引
df = df.reset_index(drop=True)

#确认是否还有空值
df.isnull().sum()

3.出版时间清洗

豆瓣图书统计可视化分析_第5张图片

观察上述出版时间一列的数据可知,存在这许多不同的时间表达方式,但是为了之后对于时间的可视化描述,我们需要在这里对时间进行“归一”化。

代码如下:

 df['出版时间']=df['出版时间'].str.replace(' ','')
 for index,row in df.iterrows():
     num=re.findall('\d+',row[3])
     num=''.join(num)[0:4]
     df.iloc[index,3]=num
 # 将出版时间转换为整数型
 df.drop(df[df['出版时间'].str.len()!=4].index,axis=0,inplace=True)
 df['出版时间']=df['出版时间'].astype(np.int32)
 # 发现出版时间超出实际时间的数据,将其清除
 df.drop(df[df['出版时间']>2019].index,inplace=True)

 3.检查页数一列的数据情况

清洗“页数”中存在乱码/不规则/标点情况

代码如下:

df['页数'].str.contains('\.').value_counts()
# 规范页数的格式,去除含有其他字符的数据比如‘.’
df['页数']=df['页数'].apply(lambda x:x.replace(',','').replace(' ',''))
df.drop(df[~(df['页数'].str.isdecimal())].index,axis=0,inplace=True)

# 转换页数的格式
df['页数']=df['页数'].astype(np.int32)
df.drop((df[df['页数']==0]).index,inplace=True)  # 清除页数为0的数据

4.对于评分,评论数量进行转型操作

代码如下:

# 转换数据类型
df['评分']=df['评分'].astype(float)
df['评论数量']=df['评论数量'].astype(np.int32)

5.对于价格列的清洗

对于价格一列当中不是纯数据类型的数据全部剔除

df['价格']=df['价格'].apply(lambda x:x.replace(',','').replace(' ',''))
for r_index,row in df.iterrows():
    if row[5].replace('.','').isdecimal()==False:
        df.drop(r_index,axis=0,inplace=True)
    elif row[5][-1].isdecimal()==False:
        df.drop(r_index,axis=0,inplace=True)

对于价格小于1的数据剔除

df.drop(df[df['价格']<1].index,inplace=True)

对于价格一列进行转型操作,更方便于计算。

df['价格']=df['价格'].astype(float)

6.对于书名一列进行清洗

由于是汉语居多,所以我们此时只需清洗书名一样的数据

代码如下:

df['书名'].value_counts()
df['书名'].duplicated().value_counts()
# 按照评论数量排名,然后去重,以保证数据可靠性
df=df.sort_values(by='评论数量',ascending=False)
df.reset_index(drop=True,inplace=True)
# 对排序后的数据进行去重
df.drop_duplicates(subset='书名', keep='first',inplace=True)
df.reset_index(drop=True,inplace=True)
# 查看是否还有重复的数据
df['书名'].value_counts()
# 清理后的数据
df.to_excel(r'douban_book.xlsx',encoding='utf_8_sig')

输出结果:

豆瓣图书统计可视化分析_第6张图片

7.出版书籍评分最高的为哪一个?

#出版社评分最高计算:
# 先统计各出版社的出版作品数量
press=df['出版社'].value_counts()
press=pd.DataFrame(press)
press=press.reset_index().rename(columns={'index':'出版集团','出版社':'出版数量'})
# 将出版作品数量大于200的出版社名称提取到列表中
lst=press[press['出版数量']>200]['出版集团'].tolist()
# 将列表中的出版社的作品平均分计算出来,并按照降序排序
press_rank=df[df['出版社'].isin(lst)].groupby(by='出版社',as_index=False).agg(
    {'评分':np.mean}).sort_values(by='评分',ascending=False)
# 保存为excel
press_rank.to_excel(r'press_rank.xlsx', index=False, encoding='utf-8')
# print(press_rank)

# 打开xlsx文件
workbook = openpyxl.load_workbook('press_rank.xlsx')

# 选择需要读取数据的sheet
sheet = workbook['Sheet1']

# 读取第二行第二列的数据
data1 = sheet.cell(row=2, column=1).value
data_list = []
for row in range(2, 7):
    data = sheet.cell(row=row, column=1).value
    data_list.append(data)

# 输出读取到的数据
print("出版社的书籍评分最高的为:",data1)
print("排名表已经存于当前目录下press_rank.xlsx中")
print("评分前五的出版社依次为:",data_list)

输出结果:

        

press_rank.xlsx:

 豆瓣图书统计可视化分析_第7张图片

8. 出版书籍最多的出版社是哪一个?

代码如下:

df1=df[df['评论数量']>100]
# 再提取出评分大于等于8的作品
df1=df1[df1['评分']>=8]
# 将过滤后的的作品按作者进行统计
writer=df1['出版社'].value_counts()
writer=pd.DataFrame(writer)
writer.reset_index(inplace=True)
writer.rename(columns={'index':'出版社','出版社':'发表数量'},inplace=True)
writer.to_excel(r'chubanshe.xlsx', index=False, encoding='utf-8')
workbook = openpyxl.load_workbook('chubanshe.xlsx')

# 选择需要读取数据的sheet
sheet1 = workbook['Sheet1']

data2 = sheet1.cell(row=2, column=1).value
data3 = sheet1.cell(row=2, column=2).value
print("*************************************************************")
print("出版书籍最多的出版社为:",data2)
print("数量为:",data3)
print("剩余排名可查看当前目录下chubanshe.xlsx")

输出结果:

 chubanshe.xlsx:

豆瓣图书统计可视化分析_第8张图片

 9.价格最高的出版社是哪一个?

代码如下:

df = pd.read_excel('book_douban1.xlsx')

# 按照某一列进行排序
df_sorted = df.sort_values('价格', ascending=False)

# 将整体表格存入新的表格中
df_sorted.to_excel('price.xlsx', index=False)
workbook1 = openpyxl.load_workbook('price.xlsx')

# 选择需要读取数据的sheet
sheet2 = workbook1['Sheet1']

data5 = sheet2.cell(row=2, column=1).value
data7 = sheet2.cell(row=2, column=6).value
print("*************************************************************")
print("价格最高的出版社为:",data5)
print("价格为:",data7)

输出结果:

三:可视化部分

这里将演示最简单的柱形图可视化,进阶可视化图将陆续更新。

对评分前 5名的出版社每年出版的图书数量画图进行比较分析。

 代码如下:

import openpyxl
from collections import Counter
import matplotlib.pyplot as plt
from matplotlib import rcParams

rcParams['font.sans-serif'] = ['SimHei'] # 设置正常显示中文标签
rcParams['axes.unicode_minus'] = False # 解决负数坐标显示问题

# 打开xlsx文件
wb = openpyxl.load_workbook('book_douban1.xlsx')

# 选择第一个sheet
sheet = wb.active

# 定义函数,用于生成柱状图
def bar_chart(title, publisher):
# 遍历第三列,输出包含publisher的行
    lis = []
    for row in sheet.iter_rows(min_row=2, min_col=3, values_only=True):
        if publisher in row:
            lis.append(row[1])
    # 使用Counter类进行计数
    counter = Counter(lis)
    # 将计数结果转换为两个列表
    x = list(counter.keys())
    y = list(counter.values())

    # 使用pyplot绘制柱状图
    plt.bar(x, y)

    # 添加图表标题和坐标轴标签
    plt.title(title)
    plt.xlabel('时间')
    plt.ylabel('出版数量')

    # 显示图表
    plt.show()
# 调用函数生成各个出版社的柱状图
bar_chart('上海古籍出版社', ' 上海古籍出版社')
bar_chart('中华书局', ' 中华书局')
bar_chart('商务印书馆', ' 商务印书馆')
bar_chart('华东师范大学出版社', ' 华东师范大学出版社')
bar_chart('华夏出版社', ' 华夏出版社')





结果展示:

豆瓣图书统计可视化分析_第9张图片

 我采用最简单易懂的方式来绘制此柱形图,不会的朋友可以留言~

你可能感兴趣的:(数据分析,python,爬虫,数据挖掘,pandas)