数据
数据集是kaggle上关于steam游戏的数据,链接在此
数据解释:
- name: 游戏名称
- average_2weeks: 最近两周不知啥的平均值数据集上也没有写
- average_foreve: 同上
- owners: 多少人把游戏加入游戏库
- players_foreve: 多少人玩过游戏
- negative: 不喜欢人数
- positive: 喜欢人数
- price: 价格(美分)
- publisher: 发布者/厂商
- score_rank: 评分情况
- userscore: 玩家打分
数据预处理
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from sqlalchemy import create_engine
import warnings
import sqlite3
import matplotlib.cm as cm
warnings.filterwarnings('ignore')
# 设置风格
%matplotlib inline
plt.style.use('ggplot')
np.random.seed(2018)
# 链接数据库
engine = create_engine('sqlite:////home/ffzs/data_analysis/visualization/seaborn/steam.sqlite')
# 导入数据
cols = ['name','average_2weeks', 'average_forever', 'owners', 'players_forever','negative', 'positive', 'price', 'publisher', 'score_rank', 'userscore']
df = pd.read_sql('select * from SteamSpy', con=engine)[cols]
df.head(2).T
缺失值查询:
df.isna().sum()
发现数据有空值和空格值:
# 将数据中的' '(空格) 转换为 ''
df = df.applymap(lambda x : x.strip() if isinstance(x, str) else x)
# 查看空值情况
(df=='').sum()
游戏名称的空值直接删除,price缺失值比较多,暂且用0代替,发布者的缺失值和空值都换成"-",score_rank空值用0替换
处理缺失值和空值:
# 删除name为空的行
df.drop(df[df.name==''].index, axis=0, inplace=True)
# 处理price缺失值
df.fillna(value={'price':0, 'publisher':'-'}, inplace=True)
# 数据类型转化为int
df.price = df.price.astype('int')
# score_rank 空白值转化成 0
df.replace({'score_rank':''},{'score_rank':0}, inplace=True)
# 更改数据类型
df.score_rank = df.score_rank.astype('int')
# publisher 空白值转化为 -
df.replace({'publisher':''},{'publisher':'-'}, inplace=True)
处理name列重复情况:
# name重名情况处理
df.name.value_counts()[df.name.value_counts()>1].count()
#>>74
# 可以查看一下
df[df.duplicated(['name'], keep=False)].sort_values('name', ascending=False)
共74个游戏重名情况,可能是游戏版本更新造成的,这里我们将游戏名重复的游戏留下一个游戏玩家最多的情况
# 根据玩家数排序
df.sort_values('owners', inplace=True)
# 丢掉其他重复数据
df.drop_duplicates(['name'], keep='last', inplace=True)
数据离散化:
# 根据玩家评分进行评级0-70为差,70-90为还可以,90-100分为好
df['us_rank'] = pd.cut(df.userscore, bins=[0,70,90,100], labels=['bad', 'medium', 'good'])
# 将价格为0的游戏设置为free
df['free'] = df.price.apply(lambda x: 'free' if x==0 else 'not_free')
存入数据库:
# 数据存入数据库 起名steam
df.to_sql('steam', con=engine, if_exists='replace')
seaborn可视化
特点
面向数据集的API,用于检查多个变量之间的关系专门支持使用分类变量显示观察结果或汇总统计数据可视化单变量或双变量分布以及在数据子集之间进行比较的选项自动估计和绘制不同类型依赖的线性回归模型变量对复杂数据集整体结构的便捷视图用于构建多绘图网格的高级抽象,可让您轻松构建复杂的可视化对matplotlib图形样式的简洁控制,具有多个内置主题用于选择忠实显示模式中的模式的调色板的工具数据Seaborn旨在使可视化成为探索和理解数据的核心部分。其面向数据集的绘图功能对包含整个数据集的数据框和数组进行操作,并在内部执行必要的语义映射和统计聚合,以生成信息图。
scatterplot()
散点图
# 数据随机抽取1000个数据
data = df[(df.owners<10000)&(df.average_forever<20000)].sample(1000)
plt.figure(figsize=(8,18))
plt.subplot(3,1,1)
# style用以点形状的区别 marker设置形状类型
markers = {"bad": "s", "medium": "X", "good": "o"}
_ = sns.scatterplot(data=data,
x='owners', y='average_forever', markers=markers,
hue='us_rank', style='us_rank')
plt.title('以点形状区分类别')
plt.subplot(3,1,2)
# size用以大小区别,sizes提供大小范围
_ = sns.scatterplot(data=data,
x='owners', y='average_forever',
hue='us_rank', size='us_rank',sizes=(20, 100))
plt.title('以点大小区分类别')
plt.subplot(3,1,3)
# palette用以调色
_ = sns.scatterplot(data=data,
x='owners', y='average_forever',
hue='us_rank', palette='cool')
plt.title('颜色使用colormap')
subplot()
线点图
# 使用style对类型进行区分
data['average_positive'] = data.positive/(data.owners)
plt.figure(figsize=(8,18))
plt.subplot(3,1,1)
# markers 设置点可见
_ = sns.lineplot(data=data, x='userscore',
y='average_positive', hue='free',
style='free', markers=True, dashes=False)
plt.title('style设置区分类型')
# 显示错误条并绘制标准错误
plt.subplot(3,1,2)
# err_style控制错误条类型
_ = sns.lineplot(data=data, x='userscore',
y='average_positive', hue='free',
err_style='bars', ci=50)
plt.title('更改错误条类型')
plt.subplot(3,1,3)
# palette更改colormap,size选取大小区分对象,sizes调整粗细范围
_ = sns.lineplot(data=data, x='userscore',
y='average_positive', hue='free',
palette='cool', size='us_rank',
sizes=(.2, 2.0))
plt.title('以线粗细为区分')
stripplot()
绘制一个散点图,其中一个变量是分类的
plt.figure(figsize=(8,18))
plt.subplot(3,1,1)
# jitter增加抖动(更分散)
_ = sns.stripplot(data=data, x='us_rank', y='negative', jitter=True,
hue='free')
plt.subplot(3,1,2)
# 横向,设置点边缘线宽度,设置点大小和类型
_ = sns.stripplot(data=data, y='us_rank', x='negative', jitter=True,
hue='free', linewidth=1, size=10, marker="D")
plt.subplot(3,1,3)
# 设置cmap,依据hue分开不同类别绘制
_ = sns.stripplot(data=data, x='us_rank', y='negative', jitter=True,
hue='free', palette='cool', dodge=True)
swarmplot()
非重叠散点图
_ = sns.swarmplot(data=data.sample(300), x='us_rank', y='positive',
hue='free')
kdeplot()
拟合并绘制单变量或双变量核密度估计值
# c控制颜色,shade加阴影
_ = sns.kdeplot(data.owners, c='g', shade=True)
# 二维数据,n_level控制分层
_ = sns.kdeplot(data.userscore,data.owners, shade=True, n_level=15,
cmap='cool', cbar=True)
distplot()
灵活地绘制单变量观测分布
plt.figure(figsize=(8,12))
plt.subplot(2,1,1)
_ = sns.distplot(data.owners, rug=True, hist=True, rug_kws=dict(color='g'),
kde_kws=dict(color='grey'),
hist_kws=dict(histtype='step', linewidth=2, color='g'))
# 最大似然高斯分布拟合绘制分布
from scipy.stats import norm
plt.subplot(2,1,2)
_ = sns.distplot(data.owners, fit=norm, kde=False)
regplot()
绘图数据和线性回归模型拟合
plt.figure(figsize=(6,6))
_ = sns.regplot(data=data.sample(100), x='userscore', y='score_rank', color='g', marker='x')
lmplot()
绘制回归模型
_ = sns.lmplot(data=data, x='negative', y='positive',hue='us_rank',
palette='cool',col='free')
boxplot()
箱形图(或盒须图)以有助于比较变量或跨分类变量水平的方式显示定量数据的分布
plt.figure(figsize=(8,16))
plt.subplot(3,1,1)
# 使用linewidth设置边线宽度
_ = sns.boxplot(data=data, x='us_rank', y='score_rank', linewidth=1.5)
# 依据hue分别表示
plt.subplot(3,1,2)
_ = sns.boxplot(data=data, x='us_rank', y='score_rank', linewidth=1.5,
hue='free', palette='RdYlBu')
# 在箱型图上显示散点
plt.subplot(3,1,3)
_ = sns.boxplot(data=data, x='us_rank', y='score_rank', palette='cool')
_ = sns.stripplot(data=data, x='us_rank', y='score_rank', color=".25")
violinplot()
绘制箱线图和核密度估计的组合
plt.figure(figsize=(8,16))
plt.subplot(3,1,1)
# 使用linewidth设置边线宽度 使用stick显示结果
_ = sns.violinplot(data=data, x='us_rank', y='score_rank', linewidth=1.5,
scale="count", inner="stick")
# 依据hue分别表示 四分位数绘制为水平线
plt.subplot(3,1,2)
_ = sns.violinplot(data=data, x='us_rank', y='score_rank', linewidth=1.5,
hue='free', palette='RdYlBu',split=True, inner="quartile")
# 在箱型图上显示散点
plt.subplot(3,1,3)
_ = sns.violinplot(data=data, x='us_rank', y='score_rank', palette='cool')
_ = sns.swarmplot(data=data, x='us_rank', y='score_rank', color=".25")
boxenplot()
为较大的数据集绘制增强的箱形图
plt.figure(figsize=(8,16))
plt.subplot(3,1,1)
# 使用linewidth设置边线宽度
_ = sns.boxenplot(data=data, x='us_rank', y='score_rank', linewidth=1.5)
# 依据hue分别表示
plt.subplot(3,1,2)
_ = sns.boxenplot(data=data, x='us_rank', y='score_rank', linewidth=1.5,
hue='free', palette='RdYlBu')
# 在箱型图上显示散点
plt.subplot(3,1,3)
_ = sns.boxenplot(data=data, x='us_rank', y='score_rank', palette='cool')
_ = sns.stripplot(data=data, x='us_rank', y='score_rank', color=".25")
pointplot()
使用散点图字形显示点估计值和置信区间
_ = sns.pointplot(data=data, x='us_rank', y='owners', hue='free',
dodge=True, markers=["o", "x"], linestyles=["-", "--"])
barplot()
_ = sns.barplot(data=data, x='us_rank', y='score_rank', palette='Blues')
countplot()
使用条形显示每个分类箱中的观察计数
_ = sns.countplot(data=data, x='us_rank', palette='Blues_d', hue='free')
heatmap()
将矩形数据绘制为颜色编码矩阵
# 获得关系列表
corr = df.corr()
plt.figure(figsize=(10,8))
_ = sns.heatmap(corr, cmap='YlGnBu',annot=True, linewidths=1)