欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据可视化

程序员文章站 2024-02-12 18:17:04
...

1 datetime 数据类型

###1 Python的datetime对象

from datetime import datetime

t1 = datetime.now()
t2 = datetime(2020,1,1)

diff = t1-t2 两个datetime对象相减得到的是timedelta对象

###2 将pandas中的数据转换成datetime

  1. 加载数据通过 pd.to_datetime转成pandas的datetime64
  2. ebola = pd.read_csv(‘data/country_timeseries.csv’,parse_dates=[0])

###3 提取日期的各个部分

d = pd.to_datetime(‘2020-06-20’)

ebola[‘year’] = ebola[‘Date’].dt.year

ebola[‘month’],ebola[‘day’] = (ebola[‘Date’].dt.month,ebola[‘Date’].dt.day)
ebola[[‘Date’,‘year’,‘month’,‘day’]].head()

4 日期运算和Timedelta

ebola[‘outbreak_d’] = ebola[‘Date’]-ebola[‘Date’].min() 得到timedelta对象

导入数据时解析日期

banks = pd.read_csv(‘data/banklist.csv’,parse_dates=[5,6])
banks.info()

添加两列,分别表示银行破产的季度和年份

banks[‘closing_quarter’],banks[‘closing_year’] = (banks[‘Closing Date’].dt.quarter,banks[‘Closing Date’].dt.year)

按照季度和年份进行分组统计

5 处理股票数据

tesla = pd.read_csv(‘data/TSLA.csv’,parse_dates=[0]) 加载数据时解析日期
tesla.info()

可以通过日期获取数据子集

tesla.loc[(tesla.Date.dt.year ==2015) & (tesla.Date.dt.month==8)]

DatetimeIndex对象

tesla.index = tesla[‘Date’]
tesla.index

tesla[‘2016’].iloc[:5]

tesla[‘2016-06’].iloc[:5]

TimedeltaIndex对象

tesla[‘ref_date’] = tesla[‘Date’]-tesla[‘Date’].min()
tesla[‘ref_date’]

tesla.index = tesla[‘ref_date’]

tesla[‘0 days’:‘4 days’]

6 日期范围

date_range函数来创建连续的日期范围

head_range = pd.date_range(start=‘2014-12-31’,end=‘2015-01-05’)

ebola_5.reindex(head_range).iloc[:,:5] 重置dataframe行索引

# 2020年1月1日这周所有的工作日
pd.date_range('2020-01-01','2020-01-07',freq='B')

# 隔一个工作日取一个工作日
pd.date_range('2020-01-01','2020-01-07',freq='2B')

7 datetime类型案例

#设置报警时间为索引
crime = crime.set_index('REPORTED_DATE')
crime.head()

设置为索引之后,可以通过具体日期获取报警记录
crime.loc['2016-05-12']

获取某个时间段内
crime.loc['2015-3-4':'2016-1-1'].sort_index()
时间段可以包括小时分钟
crime.loc['2015-3-4 22':'2016-1-1 23:45:00'].sort_index()

查询凌晨两点到五点的报警记录
crime.between_time('2:00', '5:00', include_end=False)

crime.at_time('5:47')

重采样
crime_sort.resample('W')
#size查看分组大小

2 Python数据可视化

1 数据可视化简介

1 数据可视化概念

数据可视化是指直观展现数据,它是数据处理过程的一部分

2 数据可视化常用库和各自特点

Matplotlib(功能强大,代码相对复杂)

Pandas (使用简单,功能稍弱)

Seaborn (推荐使用)

echarts 和 pyecharts (追求可视化效果,推荐使用)

数据分析的过程中可视化,推荐使用 Seaborn,理由代码简单,效果不错

追求展示效果,可以使用pyecharts,效果炫酷

2 Matplotlib绘图

1 Matplotlib绘图入门

状态接口

plt.figure(figsize=(15,3)) #figure 创建画布 figsize指定画布大小
plt.plot(x, y) #plot 绘图

面向对象

fig, ax = plt.subplots(figsize=(15,3)) #创建坐标轴对象
ax.plot(x, y) #调用坐标轴的绘图方法

2 matplotlib 数据可视化案例

通过Anscombe数据集说明数据可视化的重要性

四个数据集,统计指标非常接近

但是画出的图形完全不同

# 创建画布
fig = plt.figure(figsize=(16,8))
# 向画布添加子图
#子图有两行两列,位置是1
axes1 = fig.add_subplot(2,2,1)
#子图有两行两列,位置是2
axes2 = fig.add_subplot(2,2,2)
#子图有两行两列,位置是3
axes3 = fig.add_subplot(2,2,3)
#子图有两行两列,位置是4
axes4 = fig.add_subplot(2,2,4)

axes1.plot(dataset_1['x'],dataset_1['y'],'*')
axes2.plot(dataset_2['x'],dataset_2['y'],'+')
axes3.plot(dataset_3['x'],dataset_3['y'],'x')
axes4.plot(dataset_4['x'],dataset_4['y'],'o')

axes1.set_title('dataset_1')
axes2.set_title('dataset_2')
axes3.set_title('dataset_3')
axes4.set_title('dataset_4')

fig.suptitle('Anscombe Data')
plt.show()

3 使用matplotlib绘制统计图

# 加载tips数据集类
tips = sns.load_dataset('tips')
print(tips.head())

单变量,变量数据分布

直方图

直方图是观察单个变量最常用的方法。这些值是经过"装箱"(bin)处理的

对数据进行分箱,统计出每个箱体中元素个数

axes1.hist(tips[‘total_bill’],bins = 10)

双变量,查看两个变量间是否有关系

散点图,散点图用于表示一个连续变量随另一个连续变量的变化所呈现的大致趋势

axes1.scatter(tips[‘total_bill’],tips[‘tip’])

多变量数据

还可以通过圆点的大小来区分变量的不同

可以通过不同的颜色来表示

axes1.scatter(x = tips[‘total_bill’],y=tips[‘tip’],s = tips[‘size’]*10,c=tips[‘sex_color’],alpha = 0.5)

3 Pandas绘图

pandas绘图API简单易用,是pandas流行的重要原因之一

1 Pandas 单变量可视化

# figsize 绘图区域大小, fontsize 字体大小 color 颜色
text_kwargs=dict(figsize = (16,8),fontsize=20,color = ['b','orange','g','r','purple','brown','pink','gray','cyan','y'])
reviews['province'].value_counts().head(10).plot.bar(**text_kwargs)

reviews['points'].value_counts().sort_index().plot.bar(**text_kwargs)

折线图

reviews[‘points’].value_counts().sort_index().plot.line()

面积图

reviews[‘points’].value_counts().sort_index().plot.area()

直方图

reviews[‘points’].plot.hist()

会受数据倾斜影响

当数据在某个维度上分布不均匀,称为数据倾斜

饼图

reviews[‘province’].value_counts().head(10).plot.pie()

2 Pandas 双变量可视化

1 散点图

reviews[reviews[‘price’] < 100].sample(100).plot.scatter(x=‘price’, y=‘points’) 如果数据量太大,则无法看清规律

2 hexplot

fig, axes = plt.subplots(ncols=1, figsize = (12,8))
reviews[reviews['price'] < 100].plot.hexbin(x='price', y='points', gridsize=15,ax = axes)
axes.set_xticks([0,20,40,60,80,100])

hexplot能展示的信息更多 通过颜色展示数量

3 堆叠图

wine_counts.plot.bar(stacked=True)

4 wine_counts.plot.area()

5 wine_counts.plot.line()

4 Seaborn 可视化

1 Seaborn简介

  • Seaborn是基于matplotlib的图形可视化python包。

sns.lineplot(data=fifa_data)

###2 Seaborn绘制单变量图

1 直方图

sns.distplot(tips[‘total_bill’]) 会同时画出直方图和密度图

ax = sns.distplot(tips[‘total_bill’],kde = False) 只画直方图

ax = sns.distplot(tips[‘total_bill’],hist = False) 只画密度图

ax = sns.distplot(tips[‘total_bill’],rug = True) 添加频数图

2 计数图(条形图)

ax = sns.countplot(‘day’,data=tips)

###3 Seaborn 双变量数据可视化

1 散点图

sns.regplot(x=‘total_bill’,y=‘tip’,data=tips) regplot不仅可以绘制散点图,还会拟合回归线,把fit_reg设置为False,将只显示散点图

lmplot函数内部会调用regplot,两者的主要区别是regplot创建坐标轴,而lmplot创建图

fig = sns.lmplot(x=‘total_bill’,y=‘tip’,data = tips)

还可以使用jointplot在每个轴上创建包含单个变量的散点图。

joint = sns.jointplot(x=‘total_bill’,y=‘tip’,data = tips) 画散点图同时在坐标轴上画出直方图

2 蜂箱图

joint = sns.jointplot(x=‘total_bill’,y=‘tip’,data = tips,kind=‘hex’) 画蜂箱图

3 2D密度图

ax = sns.kdeplot(data=tips[‘total_bill’],data2=tips[‘tip’],shade=False) #是否填充轮廓

kde_joint = sns.jointplot(x = ‘total_bill’,y=‘tip’,data=tips,kind = ‘kde’) 在坐标轴上画出一维密度图

4 条形图

sns.barplot(x=‘time’,y=‘total_bill’,data=tips) 统计平均值

5 箱线图

箱线图用于显示多种统计信息:最小值,1/4分位,中位数,3/4分位,最大值,以及离群值(如果有)

sns.boxplot(x=‘time’,y=‘total_bill’,data = tips)

6 小提琴图

ax = sns.violinplot(x=‘time’,y=‘total_bill’,data = tips)

7 成对关系

可以使用pairplot函数把所有成对关系绘制出来

fig = sns.pairplot(tips)

可以使用pairgrid手动指定图的上半部分和下半部分

4 多变量数据

如果想在图中包含更多信息,可以使用颜色、大小和形状来区分它们

ax = sns.violinplot(x=‘time’,y=‘total_bill’,hue=‘sex’,data = tips,split = True)

通过大小和形状区分

markers=[‘o’,‘x’] 通过markers指定不同的形状

分面 把数据分成若干个类别,每个类别画在一个字图中

anscombe_plot = sns.lmplot(x = ‘x’,y=‘y’,data = anscombe,fit_reg = False,col = ‘dataset’,col_wrap = 2)

facet = sns.FacetGrid(tips,col = ‘time’,size = 5)
facet.map(sns.distplot,‘total_bill’,rug = True)

Seaborn有5中样式

  • darkgrid 黑色网格(默认)
  • whitegrid 白色网格
  • dark 黑色背景
  • white 白色背景
  • ticks

sns.set_style(‘whitegrid’)

5 Echarts和Pyecharts

https://pyecharts.org/#/zh-cn/assets_host 配置渲染资源

1 Echarts 和 Pyecharts简介

pyechart是一个用书生成Echarts图表的Python开源类库

使用echart的绘图效果比matplotlib等更加炫酷

pyecharts 0.X版本和 1.X版本 API变化较大,不能向下兼容

2 案例数据说明

案例使用从招聘网站(拉钩、智联、前程无忧、猎聘)上爬取的一周之内数据分析在招岗位数据

分析目标:哪些公司在招聘数据分析,哪些城市数据分析的需求大,不同城市数据分析的薪资情况,数据分析对工作年限的要求,数据分析对学历的要求

3 哪些城市在数据分析机会多

city_job_list = job.groupby(‘city’)[‘url’].count().sort_values(ascending = False)

from pyecharts import options as opts
from pyecharts.charts import Bar
c = (
    Bar() #创建柱状图
    .add_xaxis(city_job_top20.index.tolist()) #添加x轴数据
    .add_yaxis('数据分析就业岗位数量', city_job_top20.values.tolist())#添加y轴数据
    .set_global_opts( #设置全局参数
        title_opts=opts.TitleOpts(title='一周内Python就业岗位数量'), #设置标题
        datazoom_opts=opts.DataZoomOpts(),#添加缩放条
    )
)
c.render_notebook() # 在juypter notebook中显示

4 哪些公司在招聘Python程序员

company_list = job.groupby(‘company_name’)[‘url’].count().sort_values(ascending = False)

from pyecharts.charts import WordCloud
c = (
    WordCloud()#创建词云图对象
    .add(series_name='哪些公司在招聘数据分析程序员', #添加标题
         data_pair=list(zip(company_list.index.tolist(),company_list.values.tolist())), 
         word_size_range=[6, 40])#指定文字大小,注意如果字体太大可能显示不全
    .set_global_opts(#设置全局参数 标题,字号
        title_opts=opts.TitleOpts(title='哪些公司在招聘数据分析程序员', 
                                  title_textstyle_opts=opts.TextStyleOpts(font_size=23))
    )
)

5 岗位数量与平均起薪分布

数据清洗,提取起薪 使用正则表达式提取起薪

数据异常值处理

将所有城市的薪资和就业岗位数合并到一起

气泡图展示数据

from pyecharts.charts import Scatter
from pyecharts.commons.utils import JsCode

c = (
    Scatter() #创建散点图对象
    .add_xaxis(salary_data.salary_down.astype(int))#添加x周数据(薪资)
    .add_yaxis(
        "数据分析岗位数量", #y轴数据说明
        [list(z) for z in zip(salary_data.job_count, salary_data.city)],#Y轴数据,岗位,城市
        label_opts=opts.LabelOpts(#Js代码控制气泡显示提示文字
            formatter=JsCode(
                "function(params){return params.value[2]}" #提示
            )
        ),
    )
    .set_global_opts(#全局变量
        title_opts=opts.TitleOpts(title="数据分析就业岗位数量与平均起薪"),#设置标题
        tooltip_opts=opts.TooltipOpts(#Js代码控制气泡弹窗提示文字
            formatter=JsCode(
                "function (params) {return params.value[2]+ '平均薪资:'+params.value[0]}"
            )
        ),
        visualmap_opts=opts.VisualMapOpts(#控制
            type_="size", max_=1500, min_=200, dimension=1
        ),
        xaxis_opts=opts.AxisOpts(min_=6000,name='平均起薪'),#设置X轴起始值,X轴名字
        yaxis_opts=opts.AxisOpts(min_=300,max_=1550,name='岗位数量'),#设置Y轴起始值,Y轴名字
    )
)

6 工作经验需求分析

工作经验的描述不尽相同,需要处理成统一格式

job.experience.fillna('未知',inplace = True)
def process_experience(x):
    if x in ['1-3年','2年经验','经验1-3年']:
        return '1-3年'
    elif x in ['3-5年','经验3-5年','3-4年经验']:
        return '3-5年'
    elif x in ['1年经验','1年以下','经验1年以下','一年以下','经验应届毕业生','不限','经验不限','无需经验','无经验']:
        return '一年以下/应届生/经验不限'
    elif x in ['5-10年','经验5-10年','5-7年经验','8-9年经验','10年以上经验','10年以上','经验10年以上']:
        return '5年以上'
    else:
        return x
    
job['exp'] = job.experience.apply(process_experience)
job['exp'].value_counts()

from pyecharts.charts import Pie
c = (
    Pie()
    .add(
        series_name="经验要求",
        data_pair=[list(z) for z in zip(
            job['exp'].value_counts().index.tolist(),# 准备数据
            job['exp'].value_counts().values.tolist()
        )],
        radius=["50%", "70%"],#圆环图,大环小环的半径大小
        label_opts=opts.LabelOpts(is_show=False, position="center"),
    )#设置图例位置
    .set_global_opts(
        title_opts=opts.TitleOpts(title="数据分析工作经验要求"),
        legend_opts=opts.LegendOpts(pos_left="right", orient="vertical"))
    .set_series_opts(
        tooltip_opts=opts.TooltipOpts(#鼠标滑过之后弹出文字格式
            trigger="item", 
            formatter="{a} <br/>{b}: {c} ({d}%)"
        ),
    )
)

6 APP Store 数据分析案例

1 案例介绍

  • 案例背景
    • 对APP下载和评分数据分析帮助App开发者获取和留存用户
    • 通过对应用商店的数据分析为开发人员提供可操作的意见
  • 通过数据分析要解决的问题
    • 免费和收费的App都集中在哪些类别
    • 收费app的价格是如何分布的,不同类别的价格分布怎样
    • App文件的大小和价格以及用户评分之间是否有关
  • 分析流程

2 数据清洗

app.drop(‘Unnamed: 0’,axis=1,inplace=True)

app[‘size_mb’] = app[‘size_bytes’] / (1024 * 1024.0)

app[‘paid’] = app[‘price’].apply(lambda x: 1 if x > 0 else 0)

app.describe()查看数据分布

app.info()查看字段类型 数量

3 单变量分析

app.price.value_counts()

bins = [0,2,10,300]
labels = ['<2', '<10','<300']
app['price_new']=pd.cut(app.price, bins, right=False, labels=labels)



app.groupby([‘prime_genre’])[‘price’].describe()

删除价格大于等于49.99的app

app.rating_count_tot.describe()