数据类型验证¶
pandera 的核心功能是它允许您验证传入原始数据的类型,以便您的数据管道可以提前失败,而不是将数据损坏传播到下游的关键应用程序。这些应用程序可能包括依赖于干净数据进行有效分析的分析、统计和机器学习用例。
我怎样指定数据类型?¶
使用pandera模式,有多种方式来指定列、索引或整个数据框的数据类型。
import pandera as pa
import pandas as pd
# schema with datatypes at the column and index level
schema_field_dtypes = pa.DataFrameSchema(
{
"column1": pa.Column(int),
"column2": pa.Column(float),
"column3": pa.Column(str),
},
index = pa.Index(int),
)
# schema with datatypes at the dataframe level, if all columns are the
# same data type
schema_df_dtypes = pa.DataFrameSchema(dtype=int)
等效的 DataFrameModel 将是:
from pandera.typing import Series, Index
class ModelFieldDtypes(pa.DataFrameModel):
column1: Series[int]
column2: Series[float]
column3: Series[str]
index: Index[int]
class ModelDFDtypes(pa.DataFrameModel):
class Config:
dtype = int
支持的pandas数据类型¶
默认情况下,pandera 支持验证 pandas 数据帧,因此 pandera 模式支持 pandas 支持的任何 数据类型:
内置的python类型,例如
int,float,str,bool等。Numpy 数据类型,例如
numpy.int_,numpy.bool__等。Pandas原生数据类型,例如
pd.StringDtype,pd.BooleanDtype,pd.DatetimeTZDtype等。任何由 pandas 支持的 字符串别名。
我们推荐使用内置的python数据类型来处理常见的数据类型,但最终由您决定如何表示这些类型。此外,如果您愿意,也可以使用pandera定义的数据类型。
例如,以下模式以六种不同的方式表示等效的整数类型:
import numpy as np
integer_schema = pa.DataFrameSchema(
{
"builtin_python": pa.Column(int),
"builtin_python": pa.Column("int"),
"string_alias": pa.Column("int64"),
"numpy_dtype": pa.Column(np.int64),
"pandera_dtype_1": pa.Column(pa.Int),
"pandera_dtype_2": pa.Column(pa.Int64),
},
)
注意
Windows的默认 int 类型是32位整数 int32。
参数化数据类型¶
需要注意的一点是,将纯Python类型(即类)声明为列的数据类型与参数化类型之间的区别,在pandas的情况下,实际上是pandas定义的特殊类的实例。例如,使用基于对象的API,我们可以轻松地将列定义为时区感知数据类型:
datetimeschema = pa.DataFrameSchema({
"dt": pa.Column(pd.DatetimeTZDtype(unit="ns", tz="UTC"))
})
然而,由于 python 的类型注解需要类型而不是对象,要通过基于类的 API 表达相同的类型,我们需要使用一个 Annotated 类型:
try:
from typing import Annotated # python 3.9+
except ImportError:
from typing_extensions import Annotated
class DateTimeModel(pa.DataFrameModel):
dt: Series[Annotated[pd.DatetimeTZDtype, "ns", "UTC"]]
或者,您可以将 dtype_kwargs 传递给
Field():
class DateTimeModel(pa.DataFrameModel):
dt: Series[pd.DatetimeTZDtype] = pa.Field(dtype_kwargs={"unit": "ns", "tz": "UTC"})
您可以在 这里阅读更多关于支持的参数化数据类型的信息。
数据类型强制转换¶
Pandera主要是一个验证库:它仅检查数据框架的架构元数据或数据值,而不更改数据框架本身的任何内容。
然而,在许多情况下,将数据值 解析,即转换为 pandera 模式中指定的数据合约是有用的。目前,pandera 唯一的转换是类型强制转换,这可以通过将 coerce=True 参数传递给模式或模式组件对象来完成:
SeriesSchema
如果提供了这个参数,调用 schema.validate 将尝试将输入的数据框值转换为指定的数据类型,而不是简单地检查列/索引的正确类型。
然后将对数据应用数据框、列和索引级别的检查,所有这些都是纯粹的 验证器。
数据类型如何与 nullable¶ 交互
参数 nullable 可以在列、索引或 SeriesSchema 级别指定,实质上是一个核心的 pandera 检查。因此,它是在前一部分描述的数据类型检查/强制转换步骤之后应用的。因此,本身不允许为 null 的数据类型即使你指定了 nullable=True 也会失败,因为 pandera 将类型检查视为一个一流的检查,这与你可能想应用于数据的任何后续检查是不同的。
对python typing模块的支持¶
0.15.0中新功能
Pandera还支持typing模块中一组有限的通用和特殊类型,以便您验证包含object值的列:
typing.Dict[K, V]typing.List[T]typing.Tuple[T, ...]typing.TypedDicttyping.NamedTuple
重要
在底层, pandera 使用 typeguard 来验证这些泛型类型。如果您安装了 typeguard >= 3.0.0, pandera 将使用 typeguard.CollectionCheckStrategy 来验证数据值中的所有项,否则它将仅检查第一个项。
例如:
import sys
from typing import Dict, List, Tuple, NamedTuple
if sys.version_info >= (3, 12):
from typing import TypedDict
# use typing_extensions.TypedDict for python < 3.9 in order to support
# run-time availability of optional/required fields
else:
from typing_extensions import TypedDict
class PointDict(TypedDict):
x: float
y: float
class PointTuple(NamedTuple):
x: float
y: float
schema = pa.DataFrameSchema(
{
"dict_column": pa.Column(Dict[str, int]),
"list_column": pa.Column(List[float]),
"tuple_column": pa.Column(Tuple[int, str, float]),
"typeddict_column": pa.Column(PointDict),
"namedtuple_column": pa.Column(PointTuple),
},
)
data = pd.DataFrame({
"dict_column": [{"foo": 1, "bar": 2}],
"list_column": [[1.0]],
"tuple_column": [(1, "bar", 1.0)],
"typeddict_column": [PointDict(x=2.1, y=4.8)],
"namedtuple_column": [PointTuple(x=9.2, y=1.6)],
})
schema.validate(data)
| 字典列 | 列表列 | 元组列 | 类型字典列 | 命名元组列 | |
|---|---|---|---|---|---|
| 0 | {'foo': 1, 'bar': 2} | [1.0] | (1, bar, 1.0) | {'x': 2.1, 'y': 4.8} | (9.2, 1.6) |
Pandera使用typeguard进行数据类型验证,使用pydantic进行数据值强制转换,前提是您在列级、索引级或数据框级指定了coerce=True。
注意
对于某些类型,比如 List[T], typeguard 只会检查第一个值的类型,例如,如果你指定 List[int],数据值 [1, "foo", 1.0] 仍然会通过。检查所有值将在未来版本的 pandera 中可配置,当 typeguard > 4.*.* 被支持时。
Pyarrow 数据类型¶
pandas 验证引擎现在支持 pyarrow 数据类型。您可以传递 pyarrow-native 数据类型,pandas 字符串别名或 pandas ArrowDtype 类,例如:
import pyarrow
pyarrow_schema = pa.DataFrameSchema({
"pyarrow_dtype": pa.Column(pyarrow.float64()),
"pandas_str_alias": pa.Column("float64[pyarrow]"),
"pandas_dtype": pa.Column(pd.ArrowDtype(pyarrow.float64())),
})
并且在使用基于类的API时,您必须指定实际类型(不支持字符串别名):
try:
from typing import Annotated # python 3.9+
except ImportError:
from typing_extensions import Annotated
class PyarrowModel(pa.DataFrameModel):
pyarrow_dtype: pyarrow.float64
pandas_dtype: Annotated[pd.ArrowDtype, pyarrow.float64()]
pandas_dtype_kwargs: pd.ArrowDtype = pa.Field(dtype_kwargs={"pyarrow_dtype": pyarrow.float64()})