我正在尝试在IPython笔记本中写一篇论文,但遇到了显示格式的一些问题。假设我有以下数据框df
,有没有办法将var1
和var2
格式化为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%。
答案 0 :(得分:79)
接受的答案建议修改原始数据以用于演示目的,这是您通常不想要的。想象一下,您需要使用这些列进行进一步分析,并且您需要通过舍入来丢失精度。
在您的情况下,您可以修改数据框中各列的格式:
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,
})
答案 1 :(得分:26)
您还可以设置float的默认格式:
pd.options.display.float_format = '{:.2f}%'.format
答案 2 :(得分:25)
使用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
之前的数字来更改显示的小数位数。
P.S。我不确定你的百分比是多少?数字已经乘以100.如果它们已经清楚,您将需要更改显示的小数位数,并删除100位乘法。
答案 3 :(得分:17)
根据@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 :(得分:3)
另一种方法是要求在更大范围的列上执行此操作
使用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
答案 5 :(得分:2)
只需:
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%
答案 6 :(得分: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处理状态。
答案 7 :(得分:1)
style.format
是矢量化的,因此我们可以简单地将其应用于整个df
(或仅将其数字列):
df[num_cols].style.format('{:,.3f}')