【问题标题】:Adding NaN changes dtype of column in Pandas dataframe在 Pandas 数据框中添加 NaN 会更改列的 dtype
【发布时间】:2021-09-07 18:49:15
【问题描述】:

我有一个 int 数据框:

   0   1   2
0  0   1   2
1  3   4   5
2  6   7   8
3  9  10  11

但是,如果我将值设置为 NaN,则整个列都会转换为浮点数!显然 int 列不能有 NaN 值。但这是为什么呢?

>>> df.iloc[2,1] = np.nan
>>> df
   0     1   2
0  0   1.0   2
1  3   4.0   5
2  6   NaN   8
3  9  10.0  11

【问题讨论】:

  • 检查type(df.iloc[2,1])的输出,看看why-is-nan-considered-as-a-float
  • @AnuragDabas 是对的,NaN 是一个浮点数。您可以尝试pd.NA替换 nan 值。

标签: python-3.x pandas dataframe nan


【解决方案1】:

出于性能原因(在这种情况下会产生很大影响),Pandas 希望您的列来自同一类型,因此会尽最大努力保持这种状态。 NaN 是一个浮点值,所有整数都可以无害地转换为浮点数,所以会发生这种情况。

如果不能,您将得到完成这项工作所需的条件:

>>> x = pd.DataFrame(np.arange(4).reshape(2,2))
>>> x
   0  1
0  0  1
1  2  3
>>> x[1].dtype
dtype('int64')
>>> x.iloc[1, 1] = 'string'
>>> x
   0       1
0  0       1
1  2  string
>>> x[1].dtype
dtype('O')

由于1 无法以合理的方式转换为字符串(无需猜测用户想要什么),因此该类型将转换为通用的对象,并且不允许进行任何优化。这为您提供了使您想要的工作所需的东西(多类型列):

>>> x[1] = x[1].astype('O') # Alternatively use a non-float NaN object
>>> x.iloc[1, 1] = np.nan  # or float('nan')
>>> x
   0    1
0  0    1
1  2  NaN

如果您不必这样做,通常根本不建议这样做。

【讨论】:

    【解决方案2】:

    使用pd.NA 而不是np.NaN 不是最好但视觉效果更好:

    >>> df.iloc[2,1] = pd.NA
    >>> df
       0     1   2
    0  0     1   2
    1  3     4   5
    2  6  <NA>   8
    3  9    10  11
    

    看起来不错,但是:

    >>> df.dtypes
    0     int64
    1    object  # <- not float, but object
    2     int64
    dtype: object
    

    您可以从文档中阅读this page

    【讨论】:

    • 使用浮点数会比 pd.NaN 更高效,因为 pd.NaN 将类型存储为字符串,字节数更少
    猜你喜欢
    • 2021-06-19
    • 2023-01-10
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 2012-06-07
    相关资源
    最近更新 更多