可空整数数据类型#
备注
IntegerArray 目前是实验性的。它的 API 或实现可能会在没有警告的情况下更改。使用 pandas.NA
作为缺失值。
在 处理缺失数据 中,我们看到 pandas 主要使用 NaN
来表示缺失数据。因为 NaN
是一个浮点数,这会强制包含任何缺失值的整数数组变成浮点数。在某些情况下,这可能没有太大关系。但如果你的一列整数是,比如说,一个标识符,转换为浮点数可能会出现问题。一些整数甚至不能表示为浮点数。
建设#
pandas 可以使用 arrays.IntegerArray
表示可能包含缺失值的整数数据。这是一个在 pandas 内部实现的 扩展类型。
In [1]: arr = pd.array([1, 2, None], dtype=pd.Int64Dtype())
In [2]: arr
Out[2]:
<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64
或者字符串别名 "Int64"
(注意大写的 "I"
)以区别于 NumPy 的 'int64'
dtype:
In [3]: pd.array([1, 2, np.nan], dtype="Int64")
Out[3]:
<IntegerArray>
[1, 2, <NA>]
Length: 3, dtype: Int64
所有类似NA的值都被替换为 pandas.NA
。
In [4]: pd.array([1, 2, np.nan, None, pd.NA], dtype="Int64")
Out[4]:
<IntegerArray>
[1, 2, <NA>, <NA>, <NA>]
Length: 5, dtype: Int64
这个数组可以像任何 NumPy 数组一样存储在 DataFrame
或 Series
中。
In [5]: pd.Series(arr)
Out[5]:
0 1
1 2
2 <NA>
dtype: Int64
你也可以将类似列表的对象传递给带有 dtype 的 Series
构造函数。
警告
目前 pandas.array()
和 pandas.Series()
使用不同的规则进行 dtype 推断。pandas.array()
将推断出一个可为空的整数 dtype。
In [6]: pd.array([1, None])
Out[6]:
<IntegerArray>
[1, <NA>]
Length: 2, dtype: Int64
In [7]: pd.array([1, 2])
Out[7]:
<IntegerArray>
[1, 2]
Length: 2, dtype: Int64
为了向后兼容,Series
推断这些为整数或浮点数数据类型。
In [8]: pd.Series([1, None])
Out[8]:
0 1.0
1 NaN
dtype: float64
In [9]: pd.Series([1, 2])
Out[9]:
0 1
1 2
dtype: int64
我们建议明确提供数据类型以避免混淆。
In [10]: pd.array([1, None], dtype="Int64")
Out[10]:
<IntegerArray>
[1, <NA>]
Length: 2, dtype: Int64
In [11]: pd.Series([1, None], dtype="Int64")
Out[11]:
0 1
1 <NA>
dtype: Int64
在未来,我们可能会为 Series
提供一个选项,以推断可空整数类型。
如果你创建一列 NA
值(例如为了稍后填充它们)使用 df['new_col'] = pd.NA
,新的列中的 dtype
将被设置为 object
。这个列的性能将比使用适当类型时差。最好使用 df['new_col'] = pd.Series(pd.NA, dtype="Int64")``(或其他支持 ``NA
的 dtype
)。
In [12]: df = pd.DataFrame()
In [13]: df['objects'] = pd.NA
In [14]: df.dtypes
Out[14]:
objects object
dtype: object
操作#
涉及整数数组的操作将表现得类似于NumPy数组。缺失值将被传播,如果需要,数据将被强制转换为另一种数据类型。
In [15]: s = pd.Series([1, 2, None], dtype="Int64")
# arithmetic
In [16]: s + 1
Out[16]:
0 2
1 3
2 <NA>
dtype: Int64
# comparison
In [17]: s == 1
Out[17]:
0 True
1 False
2 <NA>
dtype: boolean
# slicing operation
In [18]: s.iloc[1:3]
Out[18]:
1 2
2 <NA>
dtype: Int64
# operate with other dtypes
In [19]: s + s.iloc[1:3].astype("Int8")
Out[19]:
0 <NA>
1 4
2 <NA>
dtype: Int64
# coerce when needed
In [20]: s + 0.01
Out[20]:
0 1.01
1 2.01
2 <NA>
dtype: Float64
这些数据类型可以作为 DataFrame
的一部分进行操作。
In [21]: df = pd.DataFrame({"A": s, "B": [1, 1, 3], "C": list("aab")})
In [22]: df
Out[22]:
A B C
0 1 1 a
1 2 1 a
2 <NA> 3 b
In [23]: df.dtypes
Out[23]:
A Int64
B int64
C object
dtype: object
这些数据类型可以合并、重塑和转换。
In [24]: pd.concat([df[["A"]], df[["B", "C"]]], axis=1).dtypes
Out[24]:
A Int64
B int64
C object
dtype: object
In [25]: df["A"].astype(float)
Out[25]:
0 1.0
1 2.0
2 NaN
Name: A, dtype: float64
诸如 sum()
的归约和分组操作也同样适用。
In [26]: df.sum(numeric_only=True)
Out[26]:
A 3
B 5
dtype: Int64
In [27]: df.sum()
Out[27]:
A 3
B 5
C aab
dtype: object
In [28]: df.groupby("B").A.sum()
Out[28]:
B
1 3
3 0
Name: A, dtype: Int64
标量 NA 值#
arrays.IntegerArray
使用 pandas.NA
作为其标量缺失值。切片一个缺失的单个元素将返回 pandas.NA
In [29]: a = pd.array([1, None], dtype="Int64")
In [30]: a[1]
Out[30]: <NA>