一、摘要
设置 DataFrame 中数据 有效位数的方法有很多,
可以用 pandas 中的 map, apply,applymap 方法,或者pandas style 中的 format方法,
也可以不使用DataFrame中的接口,而是用单独的 %.f 和 format格式化方法 或者 round 方法格式化数据。
本文主要对在做 display 自定义效数有效位数 等其他style 设置 实践中遇到的一些错误和学到的文章做一个总结。
二、 场景和需求:
为 dataframe 中的数(数值)设置显示的小数位数。
数据类型不固定(考虑有字符串,数值类型),数据不固定(有None, nan 和来自EXCEL 或者 formulas(可以解析excel公式的python第三方库)错误值 #VALUE! )
-
三、思路:
3.1 判断数据是否是数值
(包括 字符串数字)
判断方法:
这里学习了菜鸟教程里面一篇文章 Python 判断字符串是否为数字 ,
里面不是单纯使用 isinstance(val, number.Number) 来判断是否是数值类型 (因为这里也需要字符串数字 比如’123’)。
具体方法如下:
#对汉字表示的数字也可分辨
def is_number(s):
try: # 如果能运行float(s)语句,返回True(字符串s是浮点数)
float(s)
return True
except ValueError: # ValueError为Python的一种标准异常,表示"传入无效的参数"
pass # 如果引发了ValueError这种异常,不做任何事情(pass:不做任何事情,一般用做占位语句)
try:
import unicodedata # 处理ASCii码的包
for i in s:
unicodedata.numeric(i) # 把一个表示数字的字符串转换为浮点数返回的函数
#return True
return True
except (TypeError, ValueError):
pass
return False
我这里没有过多考虑汉字表示的数字等,所以只用到了:
def is_number(s):
try: # 如果能运行float(s)语句,返回True(字符串s是浮点数)
float(s)
return True
except ValueError: # ValueError为Python的一种标准异常,表示"传入无效的参数"
pass # 如果引发了ValueError这种异常,不做任何事情(pass:不做任何事情,一般用做占位语句)
3.2 即便是数值类型, 其中也有 nan 这种数据
最后又添加了 是否是 nan 的判断, 这里有一篇教程 python中nan的比较, 是使用 val != val 判断的。
所以最终的判断是否是数字的代码如下:
def is_valid_number(val):
if val is None:
return False
if isinstance(val, Number):
if val != val:
return False
return True
try:
float(val)
return True
except ValueError:
return False
3.3 格式化数据设置有效位数
这里之前使用了很多办法,比如 :
3.3.1 在style 样式控制中进行格式化再链式调用其他样式控制。
pamdas.DataFrame.style.format (转自 Pandas Style 为数据表格美颜 )
- 类似字符串
e.g. .format('{:.4f}')
但是这种办法一旦遇到 字符串类型数据 就报错了,当前还没有想到解决办法。
- 使用 字典 格式化 特定 的列
e.g. df.style.format({'B': "{:0<4.0f}", 'D': '{:+.2f}'})
- 使用 lambda 函数
e.g. df.style.format({"B": lambda x: "±{:.2f}".format(abs(x))})
直接报错,连浮点数都不能处理,当前还不知道是不是 style 链式调用的问题,还是 format 方法 不能传入 func 函数作为参数。(需要做记录再找下原因)
3.3.2 DataFrame.applymap重新获取一个已经格式化有效数字的 DataFrame, 再使用 df.style.applymap() 做其他格式化操作
DataFrame.applymap
(当前采用的这种办法, )
(
这里找了很多教程, 其中有用到的有 :
(1)Python浮点数控制小数精度 , 里面有个 round 函数。
但是这种办法,最后 display 显示的时候,会在 有效位 后 4 位后面,会多显示 2 个 0。
比如 2.123400
(2)python 浮点数指定位数
也是字符串格式方法,’%[width][.precision]f’ 这里要注意,格式化以后不再是 float, 而是 str 类型。
(4)[python输出指定位数小数](https://blog.csdn.net/u013925378/article/details/103383746)<br />**)**
我这里的办法是先获取一个新的 格式化好的DataFrame, 再做样式控制和 display。
代码里 先判断是否是数字, 然后先强转成 float (为了正常处理字符串类型的数字)。
def format_significant_digits(val):
if is_valid_number(val):
return "{:.4f}".format(float(val))
return val
最终使用 data_frame = data_frame.applymap(format_significant_digits)
获取格式化有效数字以后的新的 DataFrame, 注意,此时 DataFrame 中的数字 数据类型 已经是 字符串。
此后,再进行其他 sytle 的链式 样式控制 并 display 显示 不会再有上面提到的问题。
最后:
- 转载了很多原创作者的文章, 如果觉得有侵权 , 还请联系本人, 2627724977@qq.com
- 本文只是个人实践学习总结笔记,文章可能有很多疏漏和错误,以及很多可以优化的解决办法,还请随意评论指正探讨。