Python综合实战案例-数据清洗&分析

写在前面:
本次是根据前文讲解的爬虫、数据清洗、分析进行的一个纵隔讲解案例,也是对自己这段时间python爬虫、数据分析方向的一个总结。

本例设计一个豆瓣读书数据⽂件,book.xlsx⽂件保存的是爬取豆瓣⽹站得到的图书数据,共 60671 条。下⾯进⾏探索性数据分析。
在这里插入图片描述

一、清洗爬取的网站数据

1. 导入数据

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', **{'family':'SimHei'})
# 导⼊数据
df = pd.read_excel('books.xlsx')
# 删除第9列
df = df.drop('Unnamed: 9', axis=1)     

2、清洗方法

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', **{'family':'SimHei'})
# 导⼊数据
df = pd.read_excel('books.xlsx')
# 删除第9列
df = df.drop('Unnamed: 9', axis=1)

# 对数据做清洗(缺失值与异常值)
df.describe()
df.info()
df.dtypes
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 60671 entries, 0 to 60670
Data columns (total 9 columns):
书名      60671 non-null object
作者      60668 non-null object
出版社     60671 non-null object
出版时间    60671 non-null object
页数      60671 non-null object
价格      60656 non-null object
ISBN    60671 non-null object
评分      60671 non-null float64
评论数量    60671 non-null object
dtypes: float64(1), object(8)
memory usage: 2.3+ MB
"""           

3. 处理页数数据

⽬前只要评分是数值型数据,我们还要将⻚数、价格、评论数量转换成数值型数据。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', **{'family':'SimHei'})
# 导⼊数据
df = pd.read_excel('books.xlsx')
# 删除第9列
df = df.drop('Unnamed: 9', axis=1)

# 对数据做清洗(缺失值与异常值)
df.describe()
df.info()
df.dtypes

print("---------------------------------")
# 前期分析

print( df['页数'].describe() )
'''
count     60671
unique     2109
top        None
freq       4267
Name: 页数, dtype: object
'''
print(  df['页数'].isnull().sum() ) # 返回:0 ,这样看不出来
print( len(df[df['页数']=='None']) ) # 返回:4267 , 看看有多少 None 值页数信息

print("---------------------------------")


# 转换

# 定义 convert_to_int ⽅法处理页数数据,如果为 None 则填充 0
import re
def convert2int(x):
    if re.match('^\d+$',str(x)):
        return x
    else:
        return 0

df['页数'] = df['页数'].apply(convert2int)

'''
# 或者⽤ lambda 表达式
df['页数'] = df['页数'].apply(lambda x: x if re.match('^\d+$', str(x)) else 0)
df['页数'] = df['页数'].astype(int)

'''

print( df['页数'].describe() )
'''
count    6.067100e+04
mean     6.883281e+06
std      1.695365e+09
min      0.000000e+00
25%      1.940000e+02
50%      2.640000e+02
75%      3.600000e+02
max      4.175936e+11
Name: 页数, dtype: float64
'''
print(  df['页数'].isnull().sum() ) # 返回:0 
print( len(df[df['页数']=='None']) ) # 返回:0 

4.处理价格数据

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', **{'family':'SimHei'})
# 导⼊数据
df = pd.read_excel('books.xlsx')
# 删除第9列
df = df.drop('Unnamed: 9', axis=1)

# 对数据做清洗(缺失值与异常值)
df.describe()
df.info()
df.dtypes



print("---------------------------------")
# 处理价格数据

df['价格'] = df['价格'].apply(lambda x: x if re.match('^[\d\.]+$', str(x)) else 0)
df['价格'] = df['价格'].astype(float)
# 价格为 0 的图书数量
print( len(df[df['价格'] == 0]) )   # 3217 

5.处理评论数量数据

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', **{'family':'SimHei'})
# 导⼊数据
df = pd.read_excel('books.xlsx')
# 删除第9列
df = df.drop('Unnamed: 9', axis=1)

# 对数据做清洗(缺失值与异常值)
df.describe()
df.info()
df.dtypes

print("---------------------------------")
# 处理评论数量数据
df['评论数量'] = df['评论数量'].apply(lambda x: x if re.match('^\d+$', str(x)) else 0)
df['评论数量'] = df['评论数量'].astype(int)

print( df.dtypes )
'''
书名       object
作者       object
出版社      object
出版时间     object
页数        int64
价格      float64
ISBN     object
评分      float64
评论数量      int32
dtype: obje
'''

二、分析爬取的网站数据

1.处理出版时间

后⾯需要⽤到年份信息,这⾥先对年份信息进⾏加⼯:处理出版时间,只要年份。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', **{'family':'SimHei'})
# 导⼊数据
df = pd.read_excel('books.xlsx')
# 删除第9列
df = df.drop('Unnamed: 9', axis=1)

# 对数据做清洗(缺失值与异常值)
df.describe()
df.info()
df.dtypes

# 处理⻚数数据
# 定义 convert_to_int ⽅法处理页数数据,如果为 None 则填充 0
import re
def convert2int(x):
    if re.match('^\d+$',str(x)):
        return x
    else:
        return 0
df['页数'] = df['页数'].apply(convert2int)

# 处理价格数据
df['价格'] = df['价格'].apply(lambda x: x if re.match('^[\d\.]+$', str(x)) else 0)
df['价格'] = df['价格'].astype(float)

# 处理评论数量数据
df['评论数量'] = df['评论数量'].apply(lambda x: x if re.match('^\d+$', str(x)) else 0)
df['评论数量'] = df['评论数量'].astype(int)

print("---------------------------------")


# 处理出版时间,只要年份
def year(s):
    y = re.findall('\d{4}',str(s))
    if len(y)>0:
        return y[0]
    return ''

df['出版年份'] = df['出版时间'].apply(year)
# 看看还有多少没有年份信息的
print( len(df[df['出版年份'] == '']) )   # 返回: 1035

2.分析图书数量与年份的关系

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")



# 按出版年份进⾏分组
grouped = df.groupby('出版年份')
data = grouped['ISBN'].count()
# 有两条数据⽐较奇怪,处理⼀下
df[df['出版年份'] == '1979']
df.loc[df.index[60632], ['书名', '出版时间', '出版年份']]
"""
书名 鲁迅作品中的绍兴⽅⾔注释
出版时间 1979/初版印
出版年份 1979
Name: 60632, dtype: object
"""
df.loc[df.index[60632], ['出版年份']] = '1979'
df[df['出版年份'] == '2002']
df.loc[df.index[4544], ['书名', '出版时间', '出版年份']]
"""
书名 俄罗斯插画作品集
出版时间 2002/2
出版年份 2002
Name: 4544, dtype: object
"""
df.loc[df.index[4544], ['出版年份']] = '2002'

# 然后按”出版年份“进⾏分组
grouped = df.groupby('出版年份')
data = grouped['ISBN'].count()
print( data )

print("---------------------------------")

# 判断前7条数据和后4条数据属于异常数据,所以删除前7后4的数据
data2 = data[7:-4]
# 准备画图,设置宽⼀点
plt.figure(figsize=(15, 5))
# 设置 x 周标签的倾斜⻆度
plt.xticks(rotation=60)
plt.xlabel('年份')
plt.ylabel('图书数量')
plt.plot(data2.index, data2.values)
plt.show()

在这里插入图片描述

3.分析图书评分与年份的关系

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")

# 按出版年份进⾏分组
grouped = df.groupby('出版年份')
data = grouped['ISBN'].count()
# 有两条数据⽐较奇怪,处理⼀下
df[df['出版年份'] == '1979']
df.loc[df.index[60632], ['书名', '出版时间', '出版年份']]
"""
书名 鲁迅作品中的绍兴⽅⾔注释
出版时间 1979/初版印
出版年份 1979
Name: 60632, dtype: object
"""
df.loc[df.index[60632], ['出版年份']] = '1979'
df[df['出版年份'] == '2002']
df.loc[df.index[4544], ['书名', '出版时间', '出版年份']]
"""
书名 俄罗斯插画作品集
出版时间 2002/2
出版年份 2002
Name: 4544, dtype: object
"""
df.loc[df.index[4544], ['出版年份']] = '2002'

# 然后按”出版年份“进⾏分组
grouped = df.groupby('出版年份')
data = grouped['ISBN'].count()
print( data )

print("---------------------------------")

data3 = grouped['评分'].mean()
data3 = data3[7:-4]
# 折线图反映年份和评分之间的关系
# 设置宽⼀点
plt.figure(figsize=(15, 5))
# 设置 x 周标签的倾斜⻆度
plt.xticks(rotation=60)
plt.xlabel('出版年份')
plt.ylabel('评分')
plt.plot(data3.index, data3.values)
# 还要画均值线
m = data3.values.mean()
plt.plot(data3.index, [m]*len(data3.index))
plt.show()

在这里插入图片描述

4.分析图书价格分布情况

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")

df2 = df[df['价格'] > 0]
# 看看有多少价格⼤于0的
len(df2)
df2['价格'].describe()
# 直⽅图显⽰图书价格分布情况
plt.figure(figsize=(15, 5))
plt.hist(df2['价格'], bins=40, range=(0, 200), rwidth=0.8)
plt.show()

在这里插入图片描述

5.出版图书最多的top20出版社

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")


# 出版书籍最多的20个出版社
data4 = df.groupby('出版社')['ISBN'].count()
plt.figure(figsize=(15, 5))
plt.title('⾼产出版社 Top20')
# 最多的是 None,要去掉,所以选择 -21:-1
data4.sort_values()[-21:-1].plot(kind='bar')
plt.show()

在这里插入图片描述

6. 图书评分较高的出版社

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")

# 评分较⾼的出版社
plt.figure(figsize=(15, 5))
plt.title('好评出版社 Top20')
data5 = df.groupby('出版社')['评分'].mean()
data5.sort_values()[-20:].plot(kind='bar')
plt.show()

在这里插入图片描述

7. 出书较多的作者

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")

# 出书较多的作者
plt.figure(figsize=(15, 5))
plt.title('作者 Top20')
data6 = df.groupby('作者')['ISBN'].count()
data6.sort_values()[-21:-1].plot(kind='bar')
plt.show()

在这里插入图片描述

8.分析评论和评论数量的关系

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")

print( df.corr() )
'''
            页数        价格        评分      评论数量
页数    1.000000 -0.000030  0.003157 -0.000658
价格   -0.000030  1.000000  0.001443 -0.001673
评分    0.003157  0.001443  1.000000  0.063536
评论数量 -0.000658 -0.001673  0.063536  1.000000
'''

9.分析评分与评论数量的关系2

# 与上面示例源代码相同,这里省略

print("---------------------------------")
print("---------------------------------")

# 评分⾼低与评论数量之间是否存在某种关系
# 当系统中安装多个Python版本时,可能存在无法导入问题,可以使用下面2行代码,指定要加载的seaborn文件所在的路径。
# 如果不存在加载问题,可以删除下面2行代码。
import sys
sys.path.append('C:\ProgramData\Anaconda3\Lib\site-packages')
# 加载seaborn
'''
Seaborn是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,
在大多数情况下使用seaborn能做出很具有吸引力的图,而使用matplotlib就能制作具有更多特色的图。
应该把Seaborn视为matplotlib的补充,而不是替代物。
同时它能高度兼容numpy与pandas数据结构以及scipy与statsmodels等统计模式。
'''
import seaborn as sns
# 计算相关性矩阵
corr = df.corr()
sns.heatmap(corr, cmap=sns.color_palette('Blues'))
plt.show()

在这里插入图片描述

写在最后:希望大家可以学到用到,多多支持!!!

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Token_w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值