原文链接: https:///styling-pandas.html 简介大家都知道 Excel 可以设定单元格格式,还支持单元格迷你图,其实 Pandas 也可以,本文参照 Chris Moffitt 的 Stylin’ with Pandas 一文,为大家简单介绍一下 Pandas 如何实现 DataFrame 的样式设置,主要内容如下: 设置 DataFrame 不同列的样式,如千分号、小数位数、货币符号、日期格式,百分比等; 突出显示 DataFrame 中某一列里符合某些条件的数据,如,按不同颜色显示某列中的最大值与最小值; 以不同渐变色展示每一行数据占总数据的比例大小,占比越大,颜色越深,占比越小,则颜色越浅; 实现类似 Excel 迷你条形图的功能,根据数据大小,在单元格里显示迷你条形图; 利用 Sparklines 支持库,配合 Pandas 绘制迷你走势图。需要先用 pip install sparklines 命令安装 Sparklines 支持库。
什么是样式?为什么与使用样式?样式的基本理念是用户在调整数据显示形式的同时,不会影响数据本身的计算操作。 最直观的样式是货币符号,如果只显示一个数字,比如 25.06,读者并不清楚这个数字代表的到底是美元、英镑、日元还是人民币,但 ¥25.06,大家就都知道这是人民币了,由此可见,样式可以让数据提供更多信息。 百分比也是数据样式的重要形式,0.12 就不如 12% 更直观,用百分比说明数据更清晰,也更简单。 Pandas 支持不同样式,可以用更易理解的方式显示数据,但并未修改数据的类型,所以依然还可以用 Pandas 提供的各种数学、日期、字符串函数处理数据。 Pandas 样式还包括内容里提及的高级样式,比如添加颜色与条形图等可视化元素。本文只是简要介绍 Pandas 样式的基本功能,方便大家快速上手,提高数据分析报表的可读性。 数据文件说明数据文件为 2018年销售汇总表.csv(见下方链接),本文件引用的是原文作者 Chris 虚构的一家企业 2018 年的销售数据,但汉化了数据表的标题,方便大家在代码中识别数据列的信息;
https://github.com/jaystone776/pandas_styling/blob/master/2018年销售汇总表.csv
文件格式从原文的 xlsx 改为 csv ; 文件共有 5 列,分别为账号(字符串)、姓名(字符串)、单品(字符串)、数量(整数)、单价(2 位小数)、金额(2 位小数)、日期(DateTime)
Jupyter Notebook 示例文件: https://github.com/jaystone776/pandas_styling/blob/master/浅谈Pandas样式.ipynb 0.1 导入 Numpy 与 Pandasimport 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}') )
调整以后,数据显示如下:
可以看到,用了 .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_max 、highlight_min 。 3. 渐变色样式只改变数字的样式,还不够,我们还想要更多,还想用颜色的深浅渐变来表示某一列数据占比的多少,其实这也是 Excel 已经提供了的功能,Pandas 也支持了。实现这一目标,需要使用 style 的 background_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年销售一览表') )
这里使用的是 style 的 bar 函数,分别需要设置几个参数,color 还是支持颜色编码与关键词,vmin 是基准值,比如销售额的基准值是 10 万,百分比的基准值是 1,subset 是针对的列,align 则代表对齐方式。 此外,还可以用 set_caption 函数设置 DataFrame 的标题。代码执行后,显示效果如下。
迷你条形图样式 5. Sparklines - 走势图走势图这种样式不是 Pandas 的内置样式,但依然很实用,也很酷,它是一个叫 sparklines 的支持库提供的。详情请参阅它的文档 ,这个模块可以为 Pandas 的 DataFrame 添加迷你走势图。 首先,导入 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 提供的图片,非常有创意。
翻译不易,四处求证、三天翻译、两天校对,只求一秒点赞 ,即右下方的 “在看”^_^
|