代码之家  ›  专栏  ›  技术社区  ›  Manuel

如何处理熊猫数据框中的小数

  •  -1
  • Manuel  · 技术社区  · 6 年前

    我有这样一个数据帧(df):

    euro    token
    200.0   65.78947368421053
    9997.8  2631.0
    

    每当只有0时,我想去掉0,但当“欧元”中有一个像8这样的小数点时,我想用小数点,就像你在货币中通常使用的那个样。 因此,“欧元”列的定义是2位小数,除非只有0位。对于“token”列,它将是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个小数点。:-)

    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
    

    正如你所看到的,第二排和第四排的情况都很糟糕。我想不出怎么解决这个问题。

    谢谢Manuel

    2 回复  |  直到 6 年前
        1
  •  1
  •   Prune    6 年前

    如果需要将存储的值精确到小数点后两位,则应使用 decimal 包裹如果您希望保持完全的准确性,但只在输出中打印两位小数,那么请参阅有关Python格式的各种教程,例如 "{:.2f}".format(euro)

    对OP评论的回应

    但看看你是如何得到汇率的:你分配了一个 float 价值,因此不再保证 确切地 底座10中的3.8;相反,它是二进制中最接近的近似值。我明白了 3.79999999999999982236431605997495353221893310546875

    如果你愿意 准确的 从打印页上看到的结果,然后 不能 在计算中使用分数和非二进制数字。要获得精确的3.8,请使用 Decimal(38) / Decimal(10)

    对下一条评论的回应

    这是同一个问题:您使用的输入包读取类型 浮动 ,它与文件中的数字字符串的表示形式不同。分数 .8 无法用二进制精确表示。因为您使用了 浮动 值而不是 Decimal .四舍五入到2位并不意味着计算机现在可以精确地表示百分之一百;这仅仅意味着您可以获得最接近的可用值。例如:

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

    解决这个问题的一种方法是 全部的 包括起始值在内的 十进制的 。另一种方法是接受微小的错误,直到打印或记录结果为止。。。 然后 在退出时四舍五入到两位小数。

        2
  •  1
  •   YOLO    6 年前

    您可以按照以下方式操作:

    #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']