添加 NaN 更改 Pandas 数据框中列的 dtype

时间:2021-06-24 09:19:10

标签: python-3.x pandas dataframe nan

我有一个 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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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

如果您没有必要,通常不建议这样做。