理解逻辑类型和语义标签#
在 Woodwork DataFrame 中,每一列都关联着三个类型信息:物理类型、逻辑类型和语义标签。
本指南深入介绍了 Woodwork 定义的所有逻辑类型和语义标签,以便用户选择最能描述其数据的逻辑类型和语义标签。作为提醒,以下是 Woodwork 类型的快速定义
物理类型:定义数据如何在磁盘或内存中存储。
逻辑类型:定义数据应如何解析或解释。
语义标签:提供关于数据含义或应如何使用的附加信息。
如果在初始化时未提供,Woodwork 将尝试推断列的 LogicalType
。列的逻辑类型会进一步决定应用何种物理类型和标准语义标签。但是,手动设置类型将使 DataFrame 的类型化更加准确。
Woodwork DataFrame 中准确的类型信息会影响数据在 Woodwork 初始化后如何被解析、转换和后续解释。因此,理解 Woodwork 的逻辑类型和语义标签对于 Woodwork 的下游使用至关重要。
有关如何设置和操作这些类型的深入指南,请参阅使用类型和标签指南。
有关如何自定义 Woodwork 类型系统的信息,请参阅自定义类型和推断指南。
请记住,Woodwork 列始终具有逻辑类型,而 Woodwork 添加的任何语义标签旨在为该逻辑类型添加额外的含义。我们将首先深入研究语义标签,以便在讨论逻辑类型时,我们可以更好地理解语义标签如何为其添加附加信息。
语义标签#
以下是 Woodwork 定义的完整语义标签集
[1]:
import woodwork as ww
ww.list_semantic_tags()
[1]:
名称 | 是标准标签 | 有效逻辑类型 | |
---|---|---|---|
0 | 数值 | True | [年龄, 小数年龄, 可空年龄, 双精度浮点, 整... |
1 | 分类 | True | [分类, 国家代码, 货币代码, 顺序...] |
2 | 索引 | False | 任何 LogicalType |
3 | 时间索引 | False | [日期时间, 年龄, 小数年龄, 可空年龄, 双精度浮点...] |
4 | 出生日期 | False | [日期时间] |
5 | 忽略 | False | 任何 LogicalType |
6 | 直通 | False | 任何 LogicalType |
标准标签#
标准标签与特定的逻辑类型关联。它们有助于指示逻辑类型可能落入的预定义类别。
'numeric'
- 应用于任何数值逻辑类型用途:在执行需要数值列的操作时,可以只选择数值列
相关属性:
series.ww.is_numeric
'category'
- 应用于任何本质上属于分类的逻辑类型用途:在执行需要分类列的操作时,可以只选择分类列
相关属性:
series.ww.is_categorical
索引标签#
当用户标识 index
或 time_index
列时,Woodwork 会将索引标签添加到 DataFrame。这些标签具有一些特殊属性,这些属性仅在 DataFrame 的上下文中被确认为真(因此,具有这些标签的任何 Series 可能不具有这些属性)。
'index'
- 指示列是 DataFrame 的索引或主键只能有一个索引列
索引列的内容必须是唯一的
索引列将移除与其逻辑类型关联的任何标准语义标签
在 pandas DataFrames 中,索引列中的数据将反映在 DataFrame 的底层索引中
'time_index'
只能有一个时间索引列
时间索引列将包含日期时间或数值数据
其他标签#
下述标签可以在 Woodwork 初始化期间或之后直接添加到列中。这些标签具有建议的含义,可以添加到将以下述方式使用的列中。Woodwork 不会自动将它们添加到 DataFrame,也不会在它们存在时直接对列采取行动。
'date_of_birth'
- 指示日期时间列应解析为出生日期'ignore'
/'passthrough'
- 指示列在特征工程或模型构建期间应被忽略,但仍应通过这些操作传递,以免丢失该列。
除了 Woodwork 在初始化时添加的标签之外,额外的标签可能有助于提高 DataFrame 的可解释性,因此鼓励用户添加任何能让他们更有效地使用数据的标签。
逻辑类型#
以下是 Woodwork 定义的所有逻辑类型。
[2]:
import woodwork as ww
ww.list_logical_types()
[2]:
名称 | 类型字符串 | 描述 | 物理类型 | 标准标签 | 是默认类型 | 已注册 | 父类型 | |
---|---|---|---|---|---|---|---|---|
0 | 地址 | address | 表示包含地址的逻辑类型... | string | {} | True | True | None |
1 | 年龄 | age | 表示包含整数的逻辑类型... | int64 | {numeric} | True | True | 整数 |
2 | 小数年龄 | age_fractional | 表示包含非负浮点数的逻辑类型... | float64 | {numeric} | True | True | 双精度浮点 |
3 | 可空年龄 | age_nullable | 表示包含整数的逻辑类型... | Int64 | {numeric} | True | True | 可空整数 |
4 | 布尔 | boolean | 表示包含二进制值的逻辑类型... | bool | {} | True | True | 可空布尔 |
5 | 可空布尔 | boolean_nullable | 表示包含二进制值的逻辑类型... | boolean | {} | True | True | None |
6 | 分类 | categorical | 表示包含无序值的逻辑类型... | 分类 | {category} | True | True | None |
7 | 国家代码 | country_code | 表示使用 ISO-3166 标准的国家代码的逻辑类型... | 分类 | {category} | True | True | 分类 |
8 | CurrencyCode | currency_code | 表示使用 ISO-4217 标准的货币代码的逻辑类型... | 分类 | {category} | True | True | 分类 |
9 | 日期时间 | datetime | 表示包含日期和时间的逻辑类型... | datetime64[ns] | {} | True | True | None |
10 | 双精度浮点 | double | 表示包含正数、负数... | float64 | {numeric} | True | True | None |
11 | 电子邮件地址 | email_address | 表示包含电子邮件地址的逻辑类型... | string | {} | True | True | 未知 |
12 | 文件路径 | filepath | 表示指定文件系统中的目录和文件位置的逻辑类型... | string | {} | True | True | None |
13 | IP地址 | ip_address | 表示包含 IP 地址的逻辑类型... | string | {} | True | True | 未知 |
14 | 整数 | integer | 表示包含正数、负数... | int64 | {numeric} | True | True | 可空整数 |
15 | 可空整数 | integer_nullable | 表示包含正数、负数... | Int64 | {numeric} | True | True | None |
16 | 经纬度 | lat_long | 表示包含经纬度对的逻辑类型... | object | {} | True | True | None |
17 | 自然语言 | natural_language | 表示包含文本或自然人类语言字符的逻辑类型... | string | {} | True | True | None |
18 | 顺序 | ordinal | 表示包含有序离散值的逻辑类型... | 分类 | {category} | True | True | 分类 |
19 | 人员全名 | person_full_name | 表示可能包含名字、中间名和姓氏的逻辑类型... | string | {} | True | True | None |
20 | 电话号码 | phone_number | 表示包含数字和字符表示电话号码的逻辑类型... | string | {} | True | True | 未知 |
21 | 邮政编码 | postal_code | 表示包含一系列邮政编码的逻辑类型... | 分类 | {category} | True | True | 分类 |
22 | 子区域代码 | sub_region_code | 表示使用 ISO-3166 标准的国家代码的逻辑类型... | 分类 | {category} | True | True | 分类 |
23 | 时间差 | timedelta | 表示指定时间持续时间的值的逻辑类型... | timedelta64[ns] | {} | True | True | 未知 |
24 | URL | url | 表示包含 URL 的逻辑类型,可能包括协议、主机名和文件名... | string | {} | True | True | 未知 |
25 | 未知 | unknown | 表示无法推断的逻辑类型... | string | {} | True | True | None |
在上面的 DataFrame 中,我们可以看到 parent_type
列。一个 LogicalType
的 parent_type
指的是当前 LogicalType
的更通用版本。有关逻辑类型之间父子关系如何影响 Woodwork 类型推断的更多详细信息,请参阅自定义类型和类型推断指南。
基础 LogicalType 类#
Woodwork 使用的所有逻辑类型都继承自基础 LogicalType
类,并且由于以下行为都存在于 LogicalType
类中,因此所有逻辑类型都具有以下行为:
所有逻辑类型都定义了一个
dtype
,该dtype
将用于具有该逻辑类型的任何列 - 这就是确定列的物理类型的方式所有逻辑类型都会执行一些基本的转换,将其转换为预期的物理类型(
dtype
)——这是 Woodwork LogicalTypes 作为数据转换器的一种形式。根据 LogicalType 的要求,LogicalType 可以将输入数据转换为预期格式。class LogicalType(object, metaclass=LogicalTypeMetaClass): """Base class for all other Logical Types""" type_string = ClassNameDescriptor() primary_dtype = 'string' standard_tags = set()
默认逻辑类型#
未知#
当 Woodwork 的类型推断未能为列返回任何 LogicalTypes 时,Woodwork 会将列的逻辑类型设置为默认 LogicalType,即 Unknown
。逻辑类型被推断为 Unknown
可能是一个很好的指示,表明用户可以进一步选择和设置更具体的逻辑类型。
物理类型:
string
下面是一个未能推断出逻辑类型的列的示例,这导致 Series 的逻辑类型为 Unknown
。但是,查看 Series 的内容,我们可以看到它包含国家代码,因此我们将逻辑类型设置为 CountryCode
。
[3]:
import pandas as pd
series = pd.Series(["AU", "US", "UA"])
unknown_series = ww.init_series(series)
unknown_series.ww
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/type_sys/utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
pd.to_datetime(
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/type_sys/utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
pd.to_datetime(
[3]:
<Series: None (Physical Type = string) (Logical Type = Unknown) (Semantic Tags = set())>
[4]:
countrycode_series = ww.init_series(unknown_series, "CountryCode")
countrycode_series.ww
[4]:
<Series: None (Physical Type = category) (Logical Type = CountryCode) (Semantic Tags = {'category'})>
数值逻辑类型#
年龄#
表示包含表示个人年龄的整数的逻辑类型。
物理类型:
int64
标准标签:
{'numeric'}
小数年龄#
表示包含表示个人年龄的非负浮点数的逻辑类型。可能包含空值。
物理类型:
float64
标准标签:
{'numeric'}
可空年龄#
表示包含表示个人年龄的整数的逻辑类型。可能包含空值。
物理类型:
Int64
标准标签:
{'numeric'}
双精度浮点#
表示包含正数和负数的逻辑类型,其中一些包含小数部分。
物理类型:
float64
标准标签:
{'numeric'}
整数#
表示包含不带小数部分的正数和负数的逻辑类型,包括零 (0)。
物理类型:
int64
标准标签:
{'numeric'}
可空整数#
表示包含不带小数部分的正数和负数的逻辑类型,包括零 (0)。可能包含空值。
物理类型:
Int64
标准标签:
{'numeric'}
下面我们将找到一个 DataFrame,其中包含每个数值 LogicalTypes 的示例
[5]:
numerics_df = pd.DataFrame(
{
"ints": [1, 2, 3, 4],
"ints_nullable": pd.Series([1, 2, None, 4], dtype="Int64"),
"floats": [0.0, 1.1, 2.2, 3.3],
"ages": [18, 22, 24, 34],
"ages_nullable": [None, 2, 22, 33],
}
)
numerics_df.ww.init(logical_types={"ages": "Age", "ages_nullable": "AgeNullable"})
numerics_df.ww
[5]:
物理类型 | 逻辑类型 | 语义标签 | |
---|---|---|---|
列 | |||
ints | int64 | 整数 | ['numeric'] |
ints_nullable | Int64 | 可空整数 | ['numeric'] |
floats | float64 | 双精度浮点 | ['numeric'] |
ages | int64 | 年龄 | ['numeric'] |
ages_nullable | Int64 | 可空年龄 | ['numeric'] |
分类逻辑类型#
分类#
表示具有相对于数据大小而言较少唯一值的逻辑类型。
物理类型:
category
推断:Woodwork 定义了一个阈值,用于衡量唯一值相对于 Series 大小的百分比,低于该阈值的 Series 将被视为分类。有关如何控制此阈值的更多信息,请参阅设置配置选项指南。
分类逻辑类型适用的一些数据示例
性别
眼睛颜色
国籍
头发颜色
口语
国家代码#
表示使用 ISO-3166 标准国家代码来代表国家的逻辑类型。支持 ISO 3166-1(国家)。这些代码应采用 Alpha-2 格式。
物理类型:
category
标准标签:
{'category'}
例如:'AU'
代表澳大利亚,'CN'
代表中国,'CA'
代表加拿大。
顺序#
顺序变量类型可以采用有序离散值。与分类类似,它通常是有限且固定数量的可能值。然而,这些离散值具有特定的顺序,并且顺序对于理解这些值至关重要。顺序变量类型可以表示为字符串或整数。
物理类型:
category
标准标签:
{'category'}
参数:
order
- 列中顺序值的顺序,从低到高
验证 - 在 DataFrame 或 Series 上的顺序列必须定义一个顺序,并且顺序的所有元素都必须存在。
顺序逻辑类型适用的一些数据示例
教育背景 (小学, 中学, 本科, 研究生)
满意度评分 (不满意, 满意, 非常满意)
辣度 (辣, 更辣, 最辣)
学生成绩 (A, B, C, D, F)
尺寸 (小, 中, 大)
邮政编码#
表示包含一系列邮政编码以代表一组地址的逻辑类型。
物理类型:
category
标准标签:
{'category'}
子区域代码#
表示使用 ISO-3166 标准子区域代码来代表更大地理区域一部分的逻辑类型。支持 ISO 3166-2(子区域)代码。这些代码应采用 Alpha-2 格式。
物理类型:
category
标准标签:
{'category'}
例如:'US-IL'
代表美国的伊利诺伊州,或 'AU-TAS'
代表澳大利亚的塔斯马尼亚州。
[6]:
categoricals_df = pd.DataFrame(
{
"categorical": pd.Series(["a", "b", "a", "a"], dtype="category"),
"ordinal": ["small", "large", "large", "medium"],
"country_code": ["AU", "US", "UA", "AU"],
"postal_code": ["90210", "60035", "SW1A", "90210"],
"sub_region_code": ["AU-NSW", "AU-TAS", "AU-QLD", "AU-QLD"],
}
)
categoricals_df.ww.init(
logical_types={
"ordinal": ww.logical_types.Ordinal(order=["small", "medium", "large"]),
"country_code": "CountryCode",
"postal_code": "PostalCode",
"sub_region_code": "SubRegionCode",
}
)
categoricals_df.ww
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/type_sys/utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
pd.to_datetime(
[6]:
物理类型 | 逻辑类型 | 语义标签 | |
---|---|---|---|
列 | |||
categorical | 分类 | 分类 | ['category'] |
ordinal | 分类 | 顺序: ['small', 'medium', 'large'] | ['category'] |
country_code | 分类 | 国家代码 | ['category'] |
postal_code | 分类 | 邮政编码 | ['category'] |
sub_region_code | 分类 | 子区域代码 | ['category'] |
其他具有特定格式的逻辑类型#
布尔#
表示包含表示 true/false 的二进制值的逻辑类型。
物理类型:
bool
可空布尔#
表示包含表示 true/false 的二进制值的逻辑类型。也可能包含空值。
物理类型:
boolean
日期时间#
日期时间是日期和/或时间的表示。日期时间变量类型可以表示为字符串或整数。
物理类型:
datetime64[ns]
转换:将把有效的字符串或数字转换为 pandas 日期时间,并可以使用
datetime_format
参数解析更多日期时间格式。参数:
datetime_format
- 列中日期时间的格式,例如:'%Y-%m-%d'
与'%m-%d-%Y'
日期时间的一些示例包括
交易时间
航班出发时间
提货时间
电子邮件地址#
表示包含电子邮件地址值的逻辑类型。
物理类型:
string
推断:使用电子邮件地址正则表达式,如果数据匹配,则意味着该列包含电子邮件地址。要了解有关控制所用正则表达式的更多信息,请参阅设置配置选项指南。
经纬度#
经纬度表示一对有序的经度、纬度对,它说明地球上的位置。元组的顺序很重要。经纬度可以表示为浮点数元组。
物理类型:
object
转换:将把输入转换为浮点数元组。任何空值将存储为
np.nan
时间差#
表示包含指定时间持续时间的值的逻辑类型。
物理类型:
timedelta64[ns]
示例可以包括
自某个事件以来的天/月/年数
航班到达延迟/提前了多久
距离生日的天数
下面,我们将看到一个包含这些逻辑类型数据的 DataFrame。像 dates
和 latlongs
这样的列,其数据将被转换为 Woodwork 期望的格式。
[7]:
df = pd.DataFrame(
{
"dates": ["2019/01/01", "2019/01/02", "2019/01/03", "2019/01/03"],
"latlongs": [
"[33.670914, -117.841501]",
"40.423599, -86.921162",
(-45.031705, None),
None,
],
"booleans": [True, True, False, True],
"bools_nullable": pd.Series([True, False, True, None], dtype="boolean"),
"timedelta": [
pd.Timedelta("1 days 00:00:00"),
pd.Timedelta("-1 days +23:40:00"),
pd.Timedelta("4 days 12:00:00"),
pd.Timedelta("-1 days +23:40:00"),
],
"emails": [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
],
}
)
df
[7]:
dates | latlongs | booleans | bools_nullable | timedelta | emails | |
---|---|---|---|---|---|---|
0 | 2019/01/01 | [33.670914, -117.841501] | True | True | 1 天 00:00:00 | [email protected] |
1 | 2019/01/02 | 40.423599, -86.921162 | True | False | -1 天 +23:40:00 | [email protected] |
2 | 2019/01/03 | (-45.031705, None) | False | True | 4 天 12:00:00 | [email protected] |
3 | 2019/01/03 | None | True | <NA> | -1 天 +23:40:00 | [email protected] |
[8]:
df.ww.init(
logical_types={
"latlongs": "LatLong",
"dates": ww.logical_types.Datetime(datetime_format="%Y/%m/%d"),
}
)
df.ww
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/type_sys/utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
pd.to_datetime(
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/type_sys/utils.py:33: UserWarning: Could not infer format, so each element will be parsed individually, falling back to `dateutil`. To ensure parsing is consistent and as-expected, please specify a format.
pd.to_datetime(
[8]:
物理类型 | 逻辑类型 | 语义标签 | |
---|---|---|---|
列 | |||
dates | datetime64[ns] | 日期时间 | [] |
latlongs | object | 经纬度 | [] |
booleans | bool | 布尔 | [] |
bools_nullable | boolean | 可空布尔 | [] |
timedelta | timedelta64[ns] | 时间差 | [] |
emails | string | 电子邮件地址 | [] |
[9]:
df
[9]:
dates | latlongs | booleans | bools_nullable | timedelta | emails | |
---|---|---|---|---|---|---|
0 | 2019-01-01 | (33.670914, -117.841501) | True | True | 1 天 00:00:00 | [email protected] |
1 | 2019-01-02 | (40.423599, -86.921162) | True | False | -1 天 +23:40:00 | [email protected] |
2 | 2019-01-03 | (-45.031705, nan) | False | True | 4 天 12:00:00 | [email protected] |
3 | 2019-01-03 | NaN | True | <NA> | -1 天 +23:40:00 | [email protected] |
字符串逻辑类型#
自然语言#
表示包含长篇文本或代表自然人类语言字符的逻辑类型
物理类型:
string
自然语言数据示例
反馈表中的“任何其他评论”
客户评论
患者笔记
地址#
表示包含地址值的逻辑类型。
物理类型:
string
文件路径#
表示指定文件系统中目录和文件位置的逻辑类型。
物理类型:
string
人员全名#
表示可能包含名字、中间名和姓氏,包括称谓和后缀的逻辑类型。
物理类型:
string
电话号码#
表示包含数字和字符代表电话号码的逻辑类型。
物理类型:
string
URL#
表示包含 URL 的逻辑类型,其中可能包括协议、主机名和文件名。
物理类型:
string
IP地址#
表示包含 IP 地址的逻辑类型,包括 IPv4 和 IPv6 地址。
物理类型:
string
[10]:
strings_df = pd.DataFrame(
{
"natural_language": [
"This is a short sentence.",
"I like to eat pizza!",
"When will humans go to mars?",
"This entry contains two sentences. Second sentence.",
],
"addresses": [
"1 Miller Drive, New York, NY 12345",
"1 Berkeley Street, Boston, MA 67891",
"26387 Russell Hill, Dallas, TX 34521",
"54305 Oxford Street, Seattle, WA 95132",
],
"filepaths": [
"/usr/local/bin",
"/Users/john.smith/dev/index.html",
"/tmp",
"../woodwork",
],
"full_names": [
"Mr. John Doe, Jr.",
"Doe, Mrs. Jane",
"James Brown",
"John Smith",
],
"phone_numbers": [
"1-(555)-123-5495",
"+1-555-123-5495",
"5551235495",
"111-222-3333",
],
"urls": [
"http://google.com",
"https://example.com/index.html",
"example.com",
"https://woodwork.alteryx.org.cn/",
],
"ip_addresses": [
"172.16.254.1",
"192.0.0.0",
"2001:0db8:0000:0000:0000:ff00:0042:8329",
"192.0.0.0",
],
}
)
strings_df.ww.init(
logical_types={
"natural_language": "NaturalLanguage",
"addresses": "Address",
"filepaths": "FilePath",
"full_names": "PersonFullName",
"phone_numbers": "PhoneNumber",
"urls": "URL",
"ip_addresses": "IPAddress",
}
)
strings_df.ww
[10]:
物理类型 | 逻辑类型 | 语义标签 | |
---|---|---|---|
列 | |||
natural_language | string | 自然语言 | [] |
addresses | string | 地址 | [] |
filepaths | string | 文件路径 | [] |
full_names | string | 人员全名 | [] |
phone_numbers | string | 电话号码 | [] |
urls | string | URL | [] |
ip_addresses | string | IP地址 | [] |
ColumnSchema 对象#
现在我们已经深入研究了语义标签和逻辑类型,我们可以开始理解它们如何一起用于构建 Woodwork 表并定义类型空间。
一个 ColumnSchema
是单个列的类型信息。我们可以从一个 Woodwork 初始化过的 DataFrame 中获取一个 ColumnSchema
,如下所示
[11]:
# Woodwork typing info for a DataFrame
retail_df = ww.demo.load_retail()
retail_df.ww
[11]:
物理类型 | 逻辑类型 | 语义标签 | |
---|---|---|---|
列 | |||
order_product_id | 分类 | 分类 | ['index'] |
order_id | 分类 | 分类 | ['category'] |
product_id | 分类 | 分类 | ['category'] |
描述 | string | 自然语言 | [] |
quantity | int64 | 整数 | ['numeric'] |
order_date | datetime64[ns] | 日期时间 | ['time_index'] |
unit_price | float64 | 双精度浮点 | ['numeric'] |
customer_name | 分类 | 分类 | ['category'] |
country | 分类 | 分类 | ['category'] |
total | float64 | 双精度浮点 | ['numeric'] |
cancelled | bool | 布尔 | [] |
以上是一个 Woodwork DataFrame 的类型信息。如果需要,我们可以在不涉及 DataFrame 实际数据的情况下,仅访问类型信息的 schema。
[12]:
# A Woodwork TableSchema
retail_df.ww.schema
[12]:
逻辑类型 | 语义标签 | |
---|---|---|
列 | ||
order_product_id | 分类 | ['index'] |
order_id | 分类 | ['category'] |
product_id | 分类 | ['category'] |
描述 | 自然语言 | [] |
quantity | 整数 | ['numeric'] |
order_date | 日期时间 | ['time_index'] |
unit_price | 双精度浮点 | ['numeric'] |
customer_name | 分类 | ['category'] |
country | 分类 | ['category'] |
total | 双精度浮点 | ['numeric'] |
cancelled | 布尔 | [] |
woodwork.table_schema.TableSchema
的表示形式唯一的不同之处在于它没有物理类型的列。
缺少物理类型是因为 TableSchema
没有数据,因此也没有数据的物理表示。我们通常依赖物理类型信息来了解对 DataFrame 有效的确切 pandas 操作,但对于不与数据关联的类型信息 schema,这些操作不相关。
现在,让我们看一下单个列的类型信息,即 woodwork.column_schema.ColumnSchema
,我们可以通过与从 DataFrame 中选择 Series 类似的方式获取它
[13]:
# Woodwork typing infor for a Series
quantity = retail_df.ww["quantity"]
quantity.ww
[13]:
<Series: quantity (Physical Type = int64) (Logical Type = Integer) (Semantic Tags = {'numeric'})>
[14]:
# A Woodwork ColumnSchema
quantity_schema = quantity.ww.schema
quantity_schema
[14]:
<ColumnSchema (Logical Type = Integer) (Semantic Tags = ['numeric'])>
上面的 column_schema
对象可以理解为不与任何数据关联的单个列的类型信息。在这种情况下,我们恰好知道该列 schema 来自哪里 - 它来自 retail_df
DataFrame 的 quantity
列。但我们也可以创建一个不与任何单个数据列关联的 ColumnSchema
。
如果我们再次查看整个 retail_df
表,我们可以看到列之间的相似点和不同点,并且我们可以用 ColumnSchema
对象或类型空间来描述 DataFrame 的这些子集。
[15]:
retail_df.ww.schema
[15]:
逻辑类型 | 语义标签 | |
---|---|---|
列 | ||
order_product_id | 分类 | ['index'] |
order_id | 分类 | ['category'] |
product_id | 分类 | ['category'] |
描述 | 自然语言 | [] |
quantity | 整数 | ['numeric'] |
order_date | 日期时间 | ['time_index'] |
unit_price | 双精度浮点 | ['numeric'] |
customer_name | 分类 | ['category'] |
country | 分类 | ['category'] |
total | 双精度浮点 | ['numeric'] |
cancelled | 布尔 | [] |
下面是几个 ColumnSchema
,它们都将包括我们的 quantity
列,但它们各自描述了一个不同的类型空间。这些 ColumnSchema
从上到下变得越来越严格
<ColumnSchema >
- 未设置任何限制;任何列都符合此定义。<ColumnSchema (Semantic Tags = ['numeric'])>
- 仅具有numeric
标签的列适用。这也可以包括 Double、Integer 和 Age 逻辑类型列。<ColumnSchema (Logical Type = Integer)>
- 此定义中仅包含逻辑类型为Integer
的列。不要求具有numeric
标签,因此索引列(已移除其标准标签)仍然适用<ColumnSchema (Logical Type = Integer) (Semantic Tags = ['numeric'])>
- 列必须具有逻辑类型Integer
并具有numeric
语义标签,不包括索引列。
通过这种方式,ColumnSchema
可以定义一个类型空间,Woodwork DataFrame 中的列可以落入其中。
检查可空逻辑类型#
一些逻辑类型支持底层数据中存在空值,而其他则不支持。这完全取决于逻辑类型的底层 primary_dtype
是否支持空值。例如,EmailAddress
逻辑类型的底层 primary dtype 是 string
。Pandas 允许 dtype 为 string
的 series 包含由 pandas.NA
sentinel 标记的空值。因此,EmailAddress
支持空值。另一方面,Integer
逻辑类型不支持空值,因为其底层 primary pandas dtype 是 int64
。Pandas 不允许 dtype 为 int64
的 series 中存在空值。然而,pandas 允许 dtype 为 Int64
的 series 中存在空值。因此,IntegerNullable
逻辑类型支持空值,因为其 primary dtype 是 Int64
。
您可以通过在列访问器上使用 nullable
来检查列是否包含可空逻辑类型。上面描述每种类型特征的部分包含关于逻辑类型是否可空的信息。
[16]:
df.ww["bools_nullable"].ww.nullable
[16]:
True