我如何操纵pandas数据框中的小数

时间:2018-05-04 22:40:55

标签: python pandas formatting numbers decimal

我有一个像这样的数据框(df):

euro    token
200.0   65.78947368421053
9997.8  2631.0

每当只有.0时,我想摆脱.0但是当有一个像.8的单个小数时,"欧元"我想要像你通常用货币那样得到小数。 所以" euro"的定义列只有2位小数,除非只有0。对于"标记"列只有18位小数,当只有0时没有显示尾随0和没有小数。

我现在读了很多,但是甚至找不到从哪里开始。任何人

有关其他问题的更新示例

import pandas as pd
import numpy as np

min_invest = 200
cps_exchange_rate_eur = Decimal(38) / Decimal(10)

df = pd.read_excel(file.xlsx,
               index_col=None,
               dtype={'euro': float},
               na_values='NA'
               )

print(df.head())
print(df.dtypes)

      email              euro
0     first@gmail.com    600.00
1     second@web.de      200.00
2     third@web.de       1997.80
3     fourth@gmail.com   200.00
4     fifth@gmx.ch       9997.80

email     object
euro     float64
dtype: object

现在我试图让2 Decimals修复。 : - )

df.loc[:, 'euro'] = np.round(df['euro'], decimals=2)
df.loc[:, 'euro_cent'] = (df['euro'] * 100).astype(int)

print(df.head()
print(df.dtypes)

                         email    euro  euro_cent
0              first@gmail.com  600.00      60000
1                second@web.de  200.00      20000
2                 third@web.de  1997.80     199779
3             fourth@gmail.com  200.00      20000
4                 fifth@gmx.ch  9997.80     999779

email         object
euro         float64
euro_cent      int64
dtype: object

正如你所看到的,它在第2行和第4行搞砸了。我无法弄清楚如何解决这个问题。

感谢Manuel

2 个答案:

答案 0 :(得分:1)

如果您需要将存储的值精确到两位小数,那么您应该使用decimal包进行算术运算。如果要保持完整的准确性,但在输出上只打印两个小数位,那么请参阅有关Python格式的各种教程,例如"{:.2f}".format(euro)

对OP评论的回应

但是看看你如何得到汇率:你分配了一个float值,所以它不再保证在基数10中完全 3.8;相反,它是二进制中最接近的近似值。我得到3.79999999999999982236431605997495353221893310546875

如果您希望完全结果来自您在打印页面上看到的结果,那么您不能在计算中使用小数,非二进制数字。要获得精确的3.8,请使用Decimal(38) / Decimal(10)

对下一条评论的回应

这是同一个问题:您正在使用读入类型float的输入包,它与文件中的数字字符串的表示形式不同。分数.8不能完全用二进制表示。第2行和第4行混乱,因为您使用float值而不是Decimal。四舍五入并不意味着计算机现在可以代表精确的百分之一;它只是意味着您获得最接近的可用值。例如:

>>> np.round(0.8, 2)
0.80000000000000004

处理此问题的一种方法是在Decimal中执行算术的所有 - 包括起始值。另一种方法是接受微小的错误,直到打印或记录结果为止...... 然后在出路时四舍五入到小数位。

答案 1 :(得分:1)

您可以这样:

#sample
euro = [2, 2.3, 3.0, 4.0, 5.4444]

new_euro = [round(x) if x == round(x) else "{0:.2f}".format(x) for x in euro]

print(new_euro)
[2, '2.30', 3, 4, '5.44']