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


一.准备数据

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

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


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)) #打印前十行进行观察

输出结果

 二.数据清洗

大概流程如下

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

1.重新命名

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

df.rename(columns={'数':'页数'}, inplace=True)
df.reset_index(drop=True, inplace=True)
df.describe()
print(df.iloc[:, 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.出版时间清洗

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

代码如下

 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')

输出结果:

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:

 

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:

 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('华夏出版社', ' 华夏出版社')





结果展示

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

原文地址:https://blog.csdn.net/HengHengZo/article/details/129976358

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_42948.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注