将某些浮动数据帧列格式化为pandas中的百分比

问题描述 投票:41回答:7

我想在IPython笔记本上写一篇论文,但是遇到了显示格式的一些问题。假设我有以下数据帧df,有没有办法将var1var2格式化为2位小数,var3格式化为百分比。

       var1        var2         var3    
id                                              
0    1.458315    1.500092   -0.005709   
1    1.576704    1.608445   -0.005122    
2    1.629253    1.652577   -0.004754    
3    1.669331    1.685456   -0.003525   
4    1.705139    1.712096   -0.003134   
5    1.740447    1.741961   -0.001223   
6    1.775980    1.770801   -0.001723    
7    1.812037    1.799327   -0.002013    
8    1.853130    1.822982   -0.001396    
9    1.943985    1.868401    0.005732

里面的数字不会乘以100,例如-0.0057 = -0.57%。

python pandas formatting ipython-notebook
7个回答
27
投票

使用round函数替换值,并格式化百分比数字的字符串表示形式:

df['var2'] = pd.Series([round(val, 2) for val in df['var2']], index = df.index)
df['var3'] = pd.Series(["{0:.2f}%".format(val * 100) for val in df['var3']], index = df.index)

round函数将浮点数舍入为函数的第二个参数提供的小数位数。

字符串格式允许您根据需要表示数字。您可以通过更改f之前的数字来更改显示的小数位数。

附:我不确定你的'百分比'数字是否已经乘以100.如果他们已经清楚你会想要改变显示的小数位数,并删除百位乘法。


81
投票

接受的答案建议修改原始数据以用于演示目的,这是您通常不想要的。想象一下,您需要使用这些列进行进一步分析,并且您需要通过舍入来丢失精度。

在您的情况下,您可以修改数据框中各列的格式:

output = df.to_string(formatters={
    'var1': '{:,.2f}'.format,
    'var2': '{:,.2f}'.format,
    'var3': '{:,.2%}'.format
})
print(output)

为了您的信息'{:,.2%}'.format(0.214)产生21.40%,所以不需要乘以100。

你没有一个漂亮的HTML表格,只有一个文本表示。如果您需要继续使用HTML,请使用to_html函数。

from IPython.core.display import display, HTML
output = df.to_html(formatters={
    'var1': '{:,.2f}'.format,
    'var2': '{:,.2f}'.format,
    'var3': '{:,.2%}'.format
})
display(HTML(output))

更新

从熊猫0.17.1开始,生活变得更轻松,我们可以立即获得一个漂亮的html表:

df.style.format({
    'var1': '{:,.2f}'.format,
    'var2': '{:,.2f}'.format,
    'var3': '{:,.2%}'.format,
})

26
投票

您还可以设置float的默认格式:

pd.options.display.float_format = '{:.2f}%'.format

20
投票

正如@linqu所建议的那样,您不应该更改您的数据以进行演示。由于pandas 0.17.1,(条件)格式化变得更容易。引用documentation

您可以使用DataFrame属性应用条件格式,即DataFrame.style的视觉样式,具体取决于其中的数据。这是一个返回pandas.Styler对象的属性,该对象具有格式化和显示DataFrames的有用方法。

对于你的例子,那将是(通常的表将显示在Jupyter中):

df.style.format({
    'var1': '{:,.2f}'.format,
    'var2': '{:,.2f}'.format,
    'var3': '{:,.2%}'.format,
})

4
投票

另一种方法是,您需要在更大范围的列上执行此操作

使用applymap

df[['var1','var2']] = df[['var1','var2']].applymap("{0:.2f}".format)
df['var3'] = df['var3'].applymap(lambda x: "{0:.2f}%".format(x*100))

如果需要在多列上应用函数,applymap非常有用;它本质上是这个具体例子的下面的缩写:

df[['var1','var2']].apply(lambda x: map(lambda x:'{:.2f}%'.format(x),x),axis=1)

下面适用的重要说明,地图applymap:

Difference between map, applymap and apply methods in Pandas


3
投票

做就是了:

df.style.format({'var1': "{:.2f}",'var2': "{:.2f}",'var3': "{:.2%}"})

得到:

var1    var2    var3
id          
0   1.46    1.50    -0.57%
1   1.58    1.61    -0.51%
2   1.63    1.65    -0.48%
3   1.67    1.69    -0.35%
4   1.71    1.71    -0.31%
5   1.74    1.74    -0.12%
6   1.78    1.77    -0.17%
7   1.81    1.80    -0.20%
8   1.85    1.82    -0.14%
9   1.94    1.87    0.57%

1
投票

作为可接受的答案的类似方法,可以被认为更具可读性,优雅和通用(YMMV),您可以利用map方法:

# OP example
df['var3'].map(lambda n: '{:,.2%}'.format(n))

# also works on a series
series_example.map(lambda n: '{:,.2%}'.format(n))

性能方面,这与OP解决方案非常接近(略慢)。

顺便说一句,如果你选择去pd.options.display.float_format路线,考虑使用上下文管理器来处理每个parallel numpy example的状态。

© www.soinside.com 2019 - 2024. All rights reserved.