浅谈 Pandas 样式

作者: 呆鸟的简书 | 来源:发表于2019-05-20 15:54 被阅读3次
    浅谈Pandas样式

    简介

    大家都知道 Excel 可以设定单元格格式,还支持单元格迷你图,其实 Pandas 也可以,本文参照 Chris MoffittStylin’ with Pandas 一文,为大家简单介绍一下 Pandas 如何实现 DataFrame 的样式设置,主要内容如下:

    1. 设置 DataFrame 不同列的样式,如千分号、小数位数、货币符号、日期格式,百分比等;

    2. 突出显示 DataFrame 中某一列里符合某些条件的数据,如,按不同颜色显示某列中的最大值与最小值;

    3. 以不同渐变色展示每一行数据占总数据的比例大小,占比越大,颜色越深,占比越小,则颜色越浅;

    4. 实现类似 Excel 迷你条形图的功能,根据数据大小,在单元格里显示迷你条形图;

    5. 利用 Sparklines 支持库,配合 Pandas 绘制迷你走势图。需要先用 pip install sparklines 命令安装 Sparklines 支持库。

    什么是样式?为什么与使用样式?

    样式的基本理念是用户在调整数据显示形式的同时,不会影响数据本身的计算操作。

    最直观的样式是货币符号,如果只显示一个数字,比如 25.06,读者并不清楚这个数字代表的到底是美元、英镑、日元还是人民币,但 ¥25.06,大家就都知道这是人民币了,由此可见,样式可以让数据提供更多信息。

    百分比也是数据样式的重要形式,0.12 就不如 12% 更直观,用百分比说明数据更清晰,也更简单。

    Pandas 支持不同样式,可以用更易理解的方式显示数据,但并未修改数据的类型,所以依然还可以用 Pandas 提供的各种数学、日期、字符串函数处理数据。

    Pandas 样式还包括内容里提及的高级样式,比如添加颜色与条形图等可视化元素。本文只是简要介绍 Pandas 样式的基本功能,方便大家快速上手,提高数据分析报表的可读性。

    数据文件说明

    1. 数据文件为 2018年销售汇总表.csv点击下载),本文件引用的是原文作者 Chris 虚构的一家企业 2018 年的销售数据,但汉化了数据表的标题,方便大家在代码中识别数据列的信息;

    2. 文件格式从原文的 xlsx 改为 csv

    3. 文件共有 5 列,分别为账号(字符串)、姓名(字符串)、单品(字符串)、数量(整数)、单价(2 位小数)、金额(2 位小数)、日期(DateTime)

    Jupyter Notebook 示例文件,点击下载

    0.1 导入 Numpy 与 Pandas

    import numpy as np
    import pandas as pd
    

    下面的代码与原文不同,原文用的是 xlsx 文件,本文用的是 csv 文件,需要解析日期。

    另外需要注意,数据文件与 ipynb 文件要在同一文件夹下。

    df = pd.read_csv('2018年销售汇总表.csv',parse_dates=['日期'])
    

    0.2 df.head() 预览数据

    df.head()

    0.3 汇总数据,根据客人姓名分组计算 2018 年每个客人的平均金额与消费总额

    df.groupby('姓名')['金额'].agg(['mean','sum'])
    
    汇总统计消费金额

    1.1 设置金额样式:货币符号、千分号、2 位小数

    可以看到平均值显示的是 6 位小数,没有货币符号,整数部分也没有千分号。此时,可以用 DataFrame 的 style.format 修饰。

    代码如下,汇总计算的代码与上面相同,但多了 .style.format('${0:,.2f}'),引号里的 $ 符号代表美元,冒号(:)后的逗号代表千分号,.2f 代表 2 位小数。

    (
        df.groupby('姓名')['金额']
        .agg(['mean', 'sum'])
        .style.format('${0:,.2f}')
    )
    

    调整以后,数据显示如下:

    货币样式示例1

    可以看到,用了 .style.format() 函数以后,DataFrame 中平均值(mean)列显示的数据变成了带美元符号标记、整数部分带千分号、小数仅保留两位的样式,这种样式更便于理解金额这一概念。

    如果只想保留整数,可使用 .style.format('${0:,.0f}'),把上面代码里的 2 改为 0,即可。

    (
        df.groupby('姓名')['金额']
        .agg(['mean', 'sum'])
        .style.format('${0:,.0f}')
    )
    
    货币样式示例2

    此时,可以看到,货币数据已经按四舍五入的原则保留了整数。

    如需了解更多 Python 字符串格式化示例,请参照 Python String Format Cookbook

    1.2 设定日期与百分比样式

    接下来用 groupby 函数,按销售日期计算每月销售金额及其占年度销售总额的比例。

    monthly_sales = df.groupby([pd.Grouper(key='日期', freq='M')])['金额'].agg(['sum']).reset_index()
    monthly_sales['月占比'] = monthly_sales['sum']/df['金额'].sum()
    
    日期与百分比示例1

    此处可以看到,日期显示的是每个月的最后一天,比例一列则显示为 6 位小数,这种样式显然非常不直观,但一列一列调整样式也不是好方法,能不能一次性调整多列数据的样式呢?答案自然是,能!用样式字典就可以了。

    format_dict = {'sum': '${0:,.0f}', '日期': '{:%Y-%m}', '月占比': '{:.2%}'}
    monthly_sales.style.format(format_dict).hide_index()
    

    上面的代码,首先把 format_dict 定义为一个样式字典,分别设置了汇总金额(sum)日期月占比三列的样式。其中,汇总金额为带美元符号、千分号、0 位小数的数字;日期为经典的“年月”格式,月占比则为带 2 位小数的百分比形式。

    第二行代码,使用 style.format() 调用了第一行代码设定的样式字典(format_dict ),并用 hide_index() 隐藏了索引,隐藏索引的功能在很多情况下都有用,大家可以试试。

    日期与百分比示例2

    这样一来,DataFrame 的数据显示就变得比较可耐了,是不是数据显示得更清晰了,而且实现起来其实也很简单。

    2. 突出显示最大值与最小值

    Pandas 还支持用颜色突出显示符合条件的数据,类似 Excel 里的条件格式,本文主要演示一下如何突出显示某列数据里的最大值(浅绿色)与最小值(红色)。

    (
        monthly_sales
        .style
        .format(format_dict)
        .hide_index()
        .highlight_max(color='lightgreen')
        .highlight_min(color='red')
    )
    
    突出显示最大值与最小值

    这里的 color 参数除了可以用lightgreen 这样的关键词以外,还可以使用 '#cd4f39' 这样的颜色代码,更灵活。而且可以设置多个条件,比如可以同时设置 highlight_maxhighlight_min

    3. 渐变色样式

    只改变数字的样式,还不够,我们还想要更多,还想用颜色的深浅渐变来表示某一列数据占比的多少,其实这也是 Excel 已经提供了的功能,Pandas 也支持了。实现这一目标,需要使用 stylebackground_gradient 函数。

    (
        monthly_sales.style
        .format(format_dict)
        .background_gradient(subset=['sum'], cmap='BuGn')
    )
    

    上述代码设定了颜色渐变针对的列,subset=['sum'],色图用的是 cmap 参数,值为'BuGn',是一种绿色的渐变色图,色图的值请参阅 matplotlib 的文档 ,还有更多色彩可选。

    显示效果如下,是不是觉得更直观了?

    渐变色样式

    4. 迷你条形图样式

    除了渐变色,Pandas 还支持在 DataFrame 单元格里显示迷你条形图。

    (
        monthly_sales
        .style
        .format(format_dict)
        .hide_index()
        .bar(color='#FFA07A', vmin=100_000, subset=['sum'], align='zero')
        .bar(color='lightblue', vmin=0, subset=['月占比'], align='zero')
        .set_caption('2018年销售一览表')
    )
    

    这里使用的是 stylebar 函数,分别需要设置几个参数,color 还是支持颜色编码与关键词,vmin 是基准值,比如销售额的基准值是 10 万,百分比的基准值是 1,subset 是针对的列,align 则代表对齐方式。

    此外,还可以用 set_caption 函数设置 DataFrame 的标题。代码执行后,显示效果如下。

    迷你条形图样式

    5. Sparklines - 走势图

    走势图这种样式不是 Pandas 的内置样式,但依然很实用,也很酷,它是一个叫 sparklines 的支持库提供的。详情请参阅它的文档 ,这个模块可以为 Pandas 的 DataFrame 添加迷你走势图。

    首先,导入 sparklines

    import sparklines
    

    接着,定义调用 sparklines 的函数;

    def sparkline_str(x):
        bins=np.histogram(x)[0]
        sl = ' '.join(sparklines(bins))
        return sl
    
    sparkline_str.__name__ = "走势图"
    

    最后,在 groupby 函数里调用定义的 sparkline_str 函数;

    df.groupby('姓名')['数量', '金额'].agg(['mean', sparkline_str])
    
    迷你走势图示例

    这种汇总功能可以很直观的显示数据,更有趣的是这个走势图是由纯文本组成的,又简单,又实用,对不?

    总结

    Pandas 的样式功能备受欢迎,尤其是分析师完成数据分析工作后,要给别人展示数据分析结果的时候,这个功能可以让你的数据分析报告更直观,更清晰。除了本文介绍的功能之外,其实还有更多样式与函数功能供你选择,本文只是引导您上手 Pandas 样式的基础入门,想要玩的更花俏,请自行研究 Pandas 官方的样式文档

    最后,感谢 Alexas_Fotos 提供的图片,非常有创意。


    【呆鸟云】翻译不易,四处求证、三天翻译、两天校对,只求一秒点赞 _

    感谢天善智能Python爱好者社区公众号一直以来对我的支持,敬请关注!

    Python爱好者社区

    ​也欢迎大家关注我的微信公众号 Python大咖谈

    Python大咖谈

    相关文章

      网友评论

        本文标题:浅谈 Pandas 样式

        本文链接:https://www.haomeiwen.com/subject/mbotzqtx.html