在 Pandas 中将浮点数转换为整数?

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

41
只要没有缺失值,你可以更改数据类型,例如 df.col = df.col.astype(int) - EdChum
1
这个问题实际上包含了两个问题,而问题标题只反映了其中一个。 - Monica Heddneck
3
对于那些在实践中发现上述方法概念正确但并不适用的人,这是我在使用Python 3.7.5和pandas X版本时成功的代码:df = df.astype(int) - Oliver.R
11个回答

299

要修改浮点数的输出,请按照以下步骤进行:

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

5
在最新的Pandas版本中,您需要在astype函数的参数中添加copy = False,以避免出现警告。 - g.stevo
需要执行 df.a = df.a.astype(float) 吗?这会复制一份数据吗(不确定如何使用 astype() 中的 copy 参数)?有没有办法“原地”更新类型? - Mr_and_Mrs_D
1
@EdChum,有没有办法防止Pandas一开始就转换类型?例如尝试DF.({'200': {'#': 354, '%': 0.9971830985915493}, '302': {'#': 1, '%': 0.0028169014084507044}})。请注意,#被转换为浮点数,它们是行而不是列。因为每个都是一个“Series”,只能存储单一的统一类型? - alancalvitti
@alancalvitti 您需要将数据类型定义为“object”以允许混合数据类型,但是,如果执行算术操作,则可能无法保留数据类型。 - EdChum
1
我认为添加以下内容是有用的:如果您这样做,所有浮点数都将被更改。要重置此操作,请使用 pd.reset_option('display.float_format') - eHarazi
显示剩余4条评论

277

使用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

7
我尝试了您的方法,但出现了ValueError错误:无法将NA转换为整数。 - MJP
6
如果存在缺失值,就不能将浮点数序列转换为整数。请参考http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na。您必须使用浮点数。 - EdChum
3
数值并不缺失,但该列有意没有为每一行指定一个数值。有没有办法解决这个问题?由于这些数值是外键ID,我需要整数类型。 - MJP
5
我进行了编辑,将所有的NaN替换为0.0。 - Ryan G
3
如果您只是修改CSV文件,最好使用以下代码:df.to_csv("path.csv",na_rep="",float_format="%.0f",index=False)。但这将编辑所有的浮点数,因此最好将外键列转换为字符串,进行操作,然后保存。 - Ryan G
显示剩余5条评论

66

考虑以下数据框:

>>> 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

7
如果值中有NaN,会怎么样? - Zhang18
3
我尝试了这个解决方案,如果出现 NaN 的情况,你将会收到这个错误:ValueError: ('cannot convert float NaN to integer', u'occurred at index <column_name>') - enri
3
可以尝试以下代码 - df['C'] = df['C'].dropna().apply(np.int64) - vsdaking

29

将所有浮点列转换为整数

>>> 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

27

使用'Int64'支持NaN

  • astype(int)astype('int64')不能处理缺失值(numpy int)
  • astype('Int64')(注意大写的I)可以处理缺失值(pandas int)
df['A'] = df['A'].astype('Int64') # capital I

假设您希望将缺失值保留为NaN。如果您计划填充它们,您可以首先使用fillna正如Ryan建议的那样


'Int64'(大写 I)的示例

  1. If the floats are already rounded, just use 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. If the floats are not rounded yet, round before astype:

    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. To read int+NaN data from a file, use dtype='Int64' to avoid the need for converting at all:

    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' is an alias for Int64Dtype:

    df['A'] = df['A'].astype(pd.Int64Dtype()) # same as astype('Int64')
    
  • Sized/signed aliases are available:

    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

22

如果您想将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 中的所有值应用 "" - Raheel
如果需要的话,它将对所有缺失的值应用空字符串(""),但其余的值将是整数。 - Krzysztof Słowiński
谢谢这个。当.astype()和.apply(np.int64)不起作用时,这个方法有效。 - Alison S
这种方法感觉很不专业,而且我看不出来为什么要使用它,因为有很多其他可选方案。 - AMC
谢谢,这是唯一一个正确处理NaN并将它们保留(作为空字符串或“N/A”),同时将其他值转换为int的答案。 - A Kareem

15

扩展 @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 文档:

errors:{'raise','ignore'},默认值 'raise'

控制提供的数据类型无效时是否引发异常。

  • raise:允许引发异常
  • ignore:禁止异常。在错误时返回原始对象

版本 0.20.0 中新增。


11

需要转换为整数的列也可以在字典中如下所示进行指定。

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

9
>>> 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

3
在问题的文本中解释了数据来自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会将“整数浮点数”转换为整数(即1.0->1),但要注意NaN等特殊情况。此参数仅在read_excel中可用。

对于现有数据框进行转换,其他评论已经提供了几种替代方案,但自v1.0.0以来,pandas具有一个有趣的函数convert_dtypes,用于这些情况:“使用支持pd.NA的dtypes将列转换为最佳可能的dtypes。”

例如:

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,这就是人们需要查看的答案。非常感谢! - Paul Wildenhain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接