我有一个像这样的数据框(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
答案 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']