【问题标题】:Convert floats to ints in Pandas?在 Pandas 中将浮点数转换为整数?
【发布时间】:2014-02-13 00:03:49
【问题描述】:

我一直在处理从 CSV 导入的数据。 Pandas 将某些列更改为浮点数,因此现在这些列中的数字显示为浮点数!但是,我需要将它们显示为整数或不带逗号。有没有办法将它们转换为整数或不显示逗号?

【问题讨论】:

  • 可以更改类型(只要没有缺失值)df.col = df.col.astype(int)
  • 本题同时为两题,本题题目仅反映其中一题。
  • 对于遇到上述问题并发现它在概念上有用但不适合您的人,这是在 python 3.7.5 中使用 pandas X 对我有用的版本:df = df.astype(int)

标签: python pandas floating-point integer dataset


【解决方案1】:

要修改浮点输出,请执行以下操作:

df= pd.DataFrame(range(5), columns=['a'])
df.a = df.a.astype(float)
df

Out[33]:

          a
0 0.0000000
1 1.0000000
2 2.0000000
3 3.0000000
4 4.0000000

pd.options.display.float_format = '{:,.0f}'.format
df

Out[35]:

   a
0  0
1  1
2  2
3  3
4  4

【讨论】:

  • 在最新版本的 pandas 中,您需要在 astype 的参数中添加 copy = False 以避免出现警告
  • 需要df.a = df.a.astype(float)吗?这是否会复制(不确定如何使用 copyastype() 的参数)?无论如何要更新“就地”类型?
  • @EdChum,有没有办法阻止 Pandas 开始转换类型?例如尝试DF.({'200': {'#': 354, '%': 0.9971830985915493}, '302': {'#': 1, '%': 0.0028169014084507044}}) 注意 # 被转换为浮点数,它们是行,而不是列。因为每个都是一个Series,只能存储一个统一类型?
  • @alancalvitti 您在这里保留这些值或dtype 的意图是什么?如果是dtype,那么您需要将这些列创建为dtypeobject,以便允许混合,否则我的建议是只使用float,在进行比较时使用np.isclose
  • @EdChum,目的是保留输入类型。所以上面的# 应该保持整数,而% 通常是浮点数。
【解决方案2】:

使用pandas.DataFrame.astype(<type>) 函数来操作列数据类型。

>>> df = pd.DataFrame(np.random.rand(3,4), columns=list("ABCD"))
>>> df
          A         B         C         D
0  0.542447  0.949988  0.669239  0.879887
1  0.068542  0.757775  0.891903  0.384542
2  0.021274  0.587504  0.180426  0.574300
>>> df[list("ABCD")] = df[list("ABCD")].astype(int)
>>> df
   A  B  C  D
0  0  0  0  0
1  0  0  0  0
2  0  0  0  0

编辑:

处理缺失值:

>>> df
          A         B     C         D
0  0.475103  0.355453  0.66  0.869336
1  0.260395  0.200287   NaN  0.617024
2  0.517692  0.735613  0.18  0.657106
>>> df[list("ABCD")] = df[list("ABCD")].fillna(0.0).astype(int)
>>> df
   A  B  C  D
0  0  0  0  0
1  0  0  0  0
2  0  0  0  0

【讨论】:

  • 我尝试了你的方法,它给了我一个 ValueError: Cannot convert NA to integer
  • @MJP 如果缺少值,您无法将系列从浮点数转换为整数请参阅pandas.pydata.org/pandas-docs/stable/…,您必须使用浮点数
  • 这些值没有丢失,但该列没有故意为每一行指定一个值。有什么办法可以解决吗?由于这些值是外键 ID,我需要整数。
  • 我进行了编辑,其中所有 NaN 都替换为 0.0。
  • 或者更好的是,如果你只是修改一个 CSV,那么: df.to_csv("path.csv",na_rep="",float_format="%.0f",index=False) 但是这将编辑所有浮点数,因此最好将 FK 列转换为字符串,进行操作,然后保存。
【解决方案3】:

考虑以下数据框:

>>> df = pd.DataFrame(10*np.random.rand(3, 4), columns=list("ABCD"))
>>> print(df)
...           A         B         C         D
... 0  8.362940  0.354027  1.916283  6.226750
... 1  1.988232  9.003545  9.277504  8.522808
... 2  1.141432  4.935593  2.700118  7.739108

使用列名列表,使用applymap() 更改多个列的类型:

>>> cols = ['A', 'B']
>>> df[cols] = df[cols].applymap(np.int64)
>>> print(df)
...    A  B         C         D
... 0  8  0  1.916283  6.226750
... 1  1  9  9.277504  8.522808
... 2  1  4  2.700118  7.739108

或者对于带有apply()的单列:

>>> df['C'] = df['C'].apply(np.int64)
>>> print(df)
...    A  B  C         D
... 0  8  0  1  6.226750
... 1  1  9  9  8.522808
... 2  1  4  2  7.739108

【讨论】:

  • 如果值中有 NaN 怎么办?
  • @Zhang18 我试过这个解决方案,如果是 NaN,你有这个错误:ValueError: ('cannot convert float NaN to integer', u'occurred at index <column_name>')
  • @enri:可以试试下面的代码-df['C'] = df['C'].dropna().apply(np.int64)
【解决方案4】:

将所有浮点列转换为 int

>>> df = pd.DataFrame(np.random.rand(5, 4) * 10, columns=list('PQRS'))
>>> print(df)
...     P           Q           R           S
... 0   4.395994    0.844292    8.543430    1.933934
... 1   0.311974    9.519054    6.171577    3.859993
... 2   2.056797    0.836150    5.270513    3.224497
... 3   3.919300    8.562298    6.852941    1.415992
... 4   9.958550    9.013425    8.703142    3.588733

>>> float_col = df.select_dtypes(include=['float64']) # This will select float columns only
>>> # list(float_col.columns.values)

>>> for col in float_col.columns.values:
...     df[col] = df[col].astype('int64')

>>> print(df)
...     P   Q   R   S
... 0   4   0   8   1
... 1   0   9   6   3
... 2   2   0   5   3
... 3   3   8   6   1
... 4   9   9   8   3

【讨论】:

    【解决方案5】:

    如果您想将pandas.DataFrame 的更多列从浮点数转换为整数,同时考虑到您可以有 NaN 值的情况,这是一个快速的解决方案。

    cols = ['col_1', 'col_2', 'col_3', 'col_4']
    for col in cols:
       df[col] = df[col].apply(lambda x: int(x) if x == x else "")
    

    我尝试了else x)else None),但结果仍然是浮点数,所以我使用了else ""

    【讨论】:

    • 它将""应用于col中的所有值
    • 如果需要,它将对所有缺失值应用空字符串 (""),但其余值将是整数。
    • 谢谢。这在 .astype() 和 .apply(np.int64) 没有的情况下有效。
    • 这感觉很老套,我认为没有理由在许多可用的替代方案中使用它。
    • 谢谢,这是正确处理 NaN 并在将其他值转换为 int 时保留它们(作为空字符串或“N/A”)的唯一答案。
    【解决方案6】:

    扩展@Ryan G 提到的pandas.DataFrame.astype(<type>) 方法的用法,可以使用errors=ignore 参数仅转换那些不产生错误的列,这显着简化了语法。显然,忽略错误时应小心谨慎,但对于这项任务来说,它非常方便。

    >>> df = pd.DataFrame(np.random.rand(3, 4), columns=list('ABCD'))
    >>> df *= 10
    >>> print(df)
    ...           A       B       C       D
    ... 0   2.16861 8.34139 1.83434 6.91706
    ... 1   5.85938 9.71712 5.53371 4.26542
    ... 2   0.50112 4.06725 1.99795 4.75698
    
    >>> df['E'] = list('XYZ')
    >>> df.astype(int, errors='ignore')
    >>> print(df)
    ...     A   B   C   D   E
    ... 0   2   8   1   6   X
    ... 1   5   9   5   4   Y
    ... 2   0   4   1   4   Z
    

    来自pandas.DataFrame.astype docs:

    错误:{‘raise’, ‘ignore’},默认‘raise’

    控制对提供的 dtype 的无效数据引发异常。

    • raise : 允许引发异常
    • 忽略:抑制异常。出错时返回原始对象

    0.20.0 版中的新功能。

    【讨论】:

      【解决方案7】:

      需要转换为int的列也可以在字典中提到如下

      df = df.astype({'col1': 'int', 'col2': 'int', 'col3': 'int'})
      

      【讨论】:

        【解决方案8】:
        >>> import pandas as pd
        >>> right = pd.DataFrame({'C': [1.002, 2.003], 'D': [1.009, 4.55], 'key': ['K0', 'K1']})
        >>> print(right)
                   C      D key
            0  1.002  1.009  K0
            1  2.003  4.550  K1
        >>> right['C'] = right.C.astype(int)
        >>> print(right)
               C      D key
            0  1  1.009  K0
            1  2  4.550  K1
        

        【讨论】:

          【解决方案9】:

          使用 'Int64' 获得 NaN 支持

          • astype(int)astype('int64') 无法处理缺失值(numpy int)
          • astype('Int64') 可以处理缺失值(pandas int)
          df['A'] = df['A'].astype('Int64') # capital I
          

          这假设您希望将缺失值保留为 NaN。如果你打算估算它们,你可以先fillnaas Ryan suggested


          'Int64' 的示例(大写I

          1. 如果浮点数已经四舍五入,只需使用astype

            df = pd.DataFrame({'A': [99.0, np.nan, 42.0]})
            
            df['A'] = df['A'].astype('Int64')
            #       A
            # 0    99
            # 1  <NA>
            # 2    42
            
          2. 如果浮点数还没有四舍五入,roundastype 之前:

            df = pd.DataFrame({'A': [3.14159, np.nan, 1.61803]})
            
            df['A'] = df['A'].round().astype('Int64')
            #       A
            # 0     3
            # 1  <NA>
            # 2     2
            
          3. 要从文件中读取 int+NaN 数据,请使用 dtype='Int64' 来完全避免转换:

            csv = io.StringIO('''
            id,rating
            foo,5
            bar,
            baz,2
            ''')
            
            df = pd.read_csv(csv, dtype={'rating': 'Int64'})
            #     id  rating
            # 0  foo       5
            # 1  bar    <NA>
            # 2  baz       2
            

          注意事项

          • 'Int64'Int64Dtype 的别名:

            df['A'] = df['A'].astype(pd.Int64Dtype()) # same as astype('Int64')
            
          • 大小/签名的别名可用:

            lower bound upper bound
            'Int8' -128 127
            'Int16' -32,768 32,767
            'Int32' -2,147,483,648 2,147,483,647
            'Int64' -9,223,372,036,854,775,808 9,223,372,036,854,775,807
            'UInt8' 0 255
            'UInt16' 0 65,535
            'UInt32' 0 4,294,967,295
            'UInt64' 0 18,446,744,073,709,551,615

          【讨论】:

            【解决方案10】:

            在问题的文本中解释了数据来自 csv。所以,我认为在读取数据时而不是之后进行转换的显示选项与主题相关。

            在数据框中导入电子表格或 csv 时,“仅整数列”通常会转换为浮点数,因为 excel 将所有数值存储为浮点数以及底层库的工作方式。

            当使用read_excelread_csv 读取文件时,有几个选项可以避免导入后的转换:

            • 参数dtype 允许传递列名和目标类型的字典,例如dtype = {"my_column": "Int64"}
            • 参数converters 可用于传递进行转换的函数,例如将NaN 更改为0。converters = {"my_column": lambda x: int(x) if x else 0}
            • 参数convert_float 会将“整数浮点数转换为int(即1.0 –> 1)”,但要注意像NaN 这样的极端情况。该参数仅在read_excel中可用

            为了在现有数据帧中进行转换,其他 cmets 提供了几种替代方案,但由于 v1.0.0 pandas 在这种情况下有一个有趣的功能:convert_dtypes,即“使用支持 pd 的 dtypes 将列转换为可能的最佳 dtypes .NA。”

            例如:

            In [3]: import numpy as np                                                                                                                                                                                         
            
            In [4]: import pandas as pd                                                                                                                                                                                        
            
            In [5]: df = pd.DataFrame( 
               ...:     { 
               ...:         "a": pd.Series([1, 2, 3], dtype=np.dtype("int64")), 
               ...:         "b": pd.Series([1.0, 2.0, 3.0], dtype=np.dtype("float")), 
               ...:         "c": pd.Series([1.0, np.nan, 3.0]), 
               ...:         "d": pd.Series([1, np.nan, 3]), 
               ...:     } 
               ...: )                                                                                                                                                                                                          
            
            In [6]: df                                                                                                                                                                                                         
            Out[6]: 
               a    b    c    d
            0  1  1.0  1.0  1.0
            1  2  2.0  NaN  NaN
            2  3  3.0  3.0  3.0
            
            In [7]: df.dtypes                                                                                                                                                                                                  
            Out[7]: 
            a      int64
            b    float64
            c    float64
            d    float64
            dtype: object
            
            In [8]: converted = df.convert_dtypes()                                                                                                                                                                            
            
            In [9]: converted.dtypes                                                                                                                                                                                           
            Out[9]: 
            a    Int64
            b    Int64
            c    Int64
            d    Int64
            dtype: object
            
            In [10]: converted                                                                                                                                                                                                 
            Out[10]: 
               a  b     c     d
            0  1  1     1     1
            1  2  2  <NA>  <NA>
            2  3  3     3     3
            
            

            【讨论】:

            • 这是人们在使用pandas >= 1.0 时需要查看的答案。非常感谢!
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-11
            相关资源
            最近更新 更多