熊猫的 pd.NA 与 np.nan
Posted
技术标签:
【中文标题】熊猫的 pd.NA 与 np.nan【英文标题】:pd.NA vs np.nan for pandas 【发布时间】:2020-05-23 17:30:18 【问题描述】:pd.NA
vs np.nan
用于熊猫。哪一个与 pandas 一起使用,为什么要使用? pandas各自的主要优缺点是什么?
同时使用它们的一些示例代码:
import pandas as pd
import numpy as np
df = pd.DataFrame( 'object': ['a', 'b', 'c',pd.NA],
'numeric': [1, 2, np.nan , 4],
'categorical': pd.Categorical(['d', np.nan,'f', 'g'])
)
输出:
| | object | numeric | categorical |
|---:|:---------|----------:|:--------------|
| 0 | a | 1 | d |
| 1 | b | 2 | nan |
| 2 | c | nan | f |
| 3 | <NA> | 4 | g |
【问题讨论】:
我很确定 pd.NA 在后端使用 np.nan。 Pandas 倾向于在后端大量使用 numpy 这是什么版本的熊猫? @roganjosh 我正在使用 Anaconda 的 v1.0.0。 "与 np.nan 相比,pd.NA 在某些运算中的行为不同。除了算术运算之外,pd.NA 在比较运算中也传播为“缺失”或“未知””来自here @kenan 不,在这种情况下,它是distinct 【参考方案1】:pd.NA
是在最近发布的pandas-1.0.0
中引入的。
我建议在 np.nan
上使用它,因为它包含在 pandas
库中,它应该与 DataFrame 一起使用。
【讨论】:
从您的链接看来,NA
现在是实验性功能,所以对于一些严重的事情,我认为现在应该避免使用它。
pd.NA
没有完全相同的功能,所以切换时要小心。 pd.NA
在相等操作中传播,np.nan
不传播。 pd.NA == 1
产生<NA>
,但np.nan == 1
产生False
。【参考方案2】:
根据docs
pd.NA 的目标是提供一个可以跨数据类型一致使用的“缺失”指标
因此,如果您的列具有多个 dtype,则使用 pd.NA
否则 np.nan
应该没问题。
但是,由于 pd.NA
似乎与 np.nan
具有相同的功能,因此最好将 pd.NA
用于所有 nan 目的
现在只有一个导入
【讨论】:
从@tdpr 提供的pandas.pydata.org/pandas-docs/stable/whatsnew/v1.0.0.html 看来NA
现在是实验性功能,所以对于一些严重的事情我认为现在应该避免它。
pd.NA
没有完全相同的功能,所以切换时要小心。 pd.NA
在相等操作中传播,np.nan
不传播。 pd.NA == 1
产生<NA>
,但np.nan == 1
产生False
。【参考方案3】:
截至目前(pandas-1.0.0 发布)我真的建议谨慎使用它。
首先,它仍然是一个实验性功能:
实验性:
pd.NA
的行为仍然可以在没有警告的情况下更改。
第二,行为不同于np.nan
:
与
np.nan
相比,pd.NA
在某些操作中的行为不同。除了算术运算,pd.NA
还在比较运算中作为“缺失”或“未知”传播。
来自release-notes的两个配额
为了展示一些额外的例子,我对插值行为感到惊讶:
创建简单的DataFrame:
df = pd.DataFrame("a": [0, pd.NA, 2], "b": [0, np.nan, 2])
df
# a b
# 0 0 0.0
# 1 <NA> NaN
# 2 2 2.0
并尝试插值:
df.interpolate()
# a b
# 0 0 0.0
# 1 <NA> 1.0
# 2 2 2.0
这有一些原因(我仍在发现),无论如何,我只想强调这些差异 - 这是一个实验性功能,在某些情况下它的行为会有所不同。
我认为这将是一个非常有用的功能,但我会非常小心“使用它而不是 np.nan
”这样的陈述。在大多数情况下可能是这样,但在您不知道的情况下可能会引起一些麻烦。
【讨论】:
【参考方案4】:pd.NA 和 np.nan 都表示数据框中的缺失值。 我注意到的主要区别是 np.nan 是一个浮点值,而 pd.NA 存储一个整数值。 如果您的数据集中包含所有整数和一些缺失值的 column1,并且缺失值被 np.nan 替换,则该列的数据类型变为浮点数,因为 np.nan 是浮点数。 但是,如果您的数据集中包含所有整数和一些缺失值的 column2,并且缺失值被 pd.NA 替换,则该列的数据类型仍然是整数,因为 pd.NA 是整数。 如果您想将任何列保留为 int,而不是将其更改为 float,这可能会很有用。
【讨论】:
【参考方案5】:pd.NA 是镇上的新人,是熊猫自己的空值。很多数据类型都是从 numpy 借来的,包括 np.nan。
从 pandas 1.0 开始,一个实验性的 pd.NA 值(单例)可用于表示标量缺失值。目前在nullable integer、boolean和专用的string数据类型中作为缺失值指示符使用。
pd.NA
的目标是提供一个“缺失”指示符,可以跨数据类型一致使用(而不是 np.nan
、None
或 pd.NaT
,具体取决于数据类型)。
让我们用所有不同的 dtypes 构建一个 df。
d = 'int': pd.Series([1, None], dtype=np.dtype("O")),
'float': pd.Series([3.0, np.NaN], dtype=np.dtype("float")),
'str': pd.Series(['test', None], dtype=np.dtype("str")),
"bool": pd.Series([True, np.nan], dtype=np.dtype("O")),
"date": pd.Series(['1/1/2000', np.NaN], dtype=np.dtype("O"))
df1 = pd.DataFrame(data=d)
df1['date'] = pd.to_datetime(df1['date'], errors='coerce')
df1.info()
df1
输出
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 int 1 non-null object
1 float 1 non-null float64
2 str 1 non-null object
3 bool 1 non-null object
4 date 1 non-null datetime64[ns]
dtypes: datetime64[ns](1), float64(1), object(3)
memory usage: 208.0+ bytes
int float str bool date
0 1 3.0 test True 2000-01-01
1 None NaN None NaN NaT
如果您有一个使用传统类型的 DataFrame 或 Series,其中缺少使用 np.nan 表示的数据,则可以使用便捷方法 convert_dtypes()
in Series 和 convert_dtypes()
in DataFrame 将数据转换为使用较新的 dtypes 整数,字符串和布尔值以及从 v1.2 开始使用 convert_integer=False
浮动。
df1[['int', 'str', 'bool', 'date']] = df1[['int', 'str', 'bool', 'date']].convert_dtypes()
df1['float'] = df1['float'].convert_dtypes(convert_integer=False)
df1.info()
df1
输出
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 int 1 non-null Int64
1 float 1 non-null Float64
2 str 1 non-null string
3 bool 1 non-null boolean
4 date 1 non-null datetime64[ns]
dtypes: Float64(1), Int64(1), boolean(1), datetime64[ns](1), string(1)
memory usage: 200.0 bytes
int float str bool date
0 1 3.0 test True 2000-01-01
1 <NA> <NA> <NA> <NA> NaT
注意大写的“F”以区别np.float32
或np.float64
,还要注意string
是新的pandas StringDtype
(来自Pandas 1.0)而不是str
或object
。
还有pd.Int64
(来自pandas 0.24)可为空的整数大写'I',而不是np.int64
。
有关数据类型的更多信息,请阅读 here 和 here。这个页面有一些关于subtypes的好信息。
我正在使用 pandas v1.2.4,因此希望我们能及时为所有数据类型提供一个通用的空值,这会温暖我们的心。
警告这是新的,实验性使用现在要小心。
【讨论】:
谢谢,但老实说pd.NA
仍然让我有些困惑。您是否尝试过直接使用此 NA 值,例如对于您的第一列(int),如下所示:'int': pd.Series([1, pd.NA], dtype=np.dtype("O"))
(pd.NA
而不是None
)?因为即使在使用convert_dtypes
方法之后,列类型也保持不变(object
而不是Int64
)。
@Nerxis 目前,pd.NA 仅用于可为空的整数、布尔值和专用字符串数据类型。这里有一个关于使用对象的讨论github.com/pandas-dev/pandas/issues/32931
是的,这个我明白,但我的意思是convert_dtypes
不会把这列对象类型转换成Int64
,这个应该支持。但是感谢您的链接,他们讨论了这个问题,包括 convert_dtypes
的函数,其中文档字符串有点混乱(与实际行为不同)。以上是关于熊猫的 pd.NA 与 np.nan的主要内容,如果未能解决你的问题,请参考以下文章