简体   繁体   English

格式化/抑制 Pandas 聚合结果的科学记数法

[英]Format / Suppress Scientific Notation from Pandas Aggregation Results

How can one modify the format for the output from a groupby operation in pandas that produces scientific notation for very large numbers?如何修改 pandas 中的 groupby 操作的输出格式,该操作为非常大的数字生成科学记数法?

I know how to do string formatting in python but I'm at a loss when it comes to applying it here.我知道如何在 python 中进行字符串格式化,但是在这里应用它时我不知所措。

df1.groupby('dept')['data1'].sum()

dept
value1       1.192433e+08
value2       1.293066e+08
value3       1.077142e+08

This suppresses the scientific notation if I convert to string but now I'm just wondering how to string format and add decimals.如果我转换为字符串,这会抑制科学记数法,但现在我只是想知道如何格式化字符串和添加小数。

sum_sales_dept.astype(str)

Granted, the answer I linked in the comments is not very helpful.当然,我在评论中链接的答案不是很有帮助。 You can specify your own string converter like so.您可以像这样指定自己的字符串转换器。

In [25]: pd.set_option('display.float_format', lambda x: '%.3f' % x)

In [28]: Series(np.random.randn(3))*1000000000
Out[28]: 
0    -757322420.605
1   -1436160588.997
2   -1235116117.064
dtype: float64

I'm not sure if that's the preferred way to do this, but it works.我不确定这是否是执行此操作的首选方式,但它确实有效。

Converting numbers to strings purely for aesthetic purposes seems like a bad idea, but if you have a good reason, this is one way:纯粹出于审美目的将数字转换为字符串似乎是个坏主意,但如果你有充分的理由,这是一种方法:

In [6]: Series(np.random.randn(3)).apply(lambda x: '%.3f' % x)
Out[6]: 
0     0.026
1    -0.482
2    -0.694
dtype: object

Here is another way of doing it, similar to Dan Allan's answer but without the lambda function:这是另一种方法,类似于Dan Allan 的答案,但没有 lambda 函数:

>>> pd.options.display.float_format = '{:.2f}'.format
>>> Series(np.random.randn(3))
0    0.41
1    0.99
2    0.10

or或者

>>> pd.set_option('display.float_format', '{:.2f}'.format)

You can use round function just to suppress scientific notation for specific dataframe:您可以使用 round 函数来抑制特定数据帧的科学记数法:

df1.round(4)

or you can suppress is globally by:或者您可以通过以下方式全局抑制:

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

If you want to style the output of a data frame in a jupyter notebook cell, you can set the display style on a per-dataframe basis:如果要在 jupyter notebook 单元格中设置数据框的输出样式,可以基于每个数据框设置显示样式:

df = pd.DataFrame({'A': np.random.randn(4)*1e7})
df.style.format("{:.1f}")

在此处输入图像描述

See the documentation here .请参阅此处的文档。

Setting a fixed number of decimal places globally is often a bad idea since it is unlikely that it will be an appropriate number of decimal places for all of your various data that you will display regardless of magnitude.全局设置固定的小数位数通常不是一个好主意,因为无论大小如何,它都不太可能是您将显示的所有各种数据的适当小数位数。 Instead, try this which will give you scientific notation only for large and very small values (and adds a thousands separator unless you omit the ","):相反,试试这个,它只会为你提供大和非常小的值的科学记数法(并添加千位分隔符,除非你省略“,”):

pd.set_option('display.float_format', lambda x: '%,g' % x)

Or to almost completely suppress scientific notation without losing precision, try this:或者要在不损失精度的情况下几乎完全抑制科学记数法,试试这个:

pd.set_option('display.float_format', str)

I had multiple dataframes with different floating point, so thx to Allans idea made dynamic length.我有多个具有不同浮点的数据帧,因此对 Allans 的想法表示感谢,使之成为动态长度。

pd.set_option('display.float_format', lambda x: f'%.{len(str(x%1))-2}f' % x)

The minus of this is that if You have last 0 in float, it will cut it.这样做的缺点是,如果你有最后一个 0 浮动,它会削减它。 So it will be not 0.000070, but 0.00007.所以它将不是 0.000070,而是 0.00007。

如果您想使用这些值,例如作为 csvfile csv.writer 的一部分,可以在创建列表之前对数字进行格式化:

df['label'].apply(lambda x: '%.17f' % x).values.tolist()

Expanding on this useful comment, here is a solution setting the formatting options only to display the results without changing options permanently:扩展这个有用的评论,这里是一个解决方案,设置格式选项只显示结果而不永久更改选项:

with pd.option_context('display.float_format', lambda x: f'{x:,.3f}'):
    display(sum_sales_dept)

dept
value1  119,243,300.0
value2  129,306,600.0
value3  107,714,200.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM