SequenceData():把表格变成标准的序列数据结构
在完成预处理(preprocessing)后,下一步是正式定义序列数据结构。换句话说,SequenceData 是 Sequenzo 中表示(represent)序列的标准入口(canonical entry point)。
你可能会问:为啥要多这一步?就像在 pandas 的 DataFrame 里先把数据装好一样,想要高效分析,得先用一个统一的容器把行、列和元数据的摆放方式定下来。
SequenceData() 做的就是这件事:建立一个专门用于序列分析的结构,保证数据被统一存放,并且:
- 状态定义与顺序一致(consistent state definitions & ordering)
- 整数编码与颜色映射可复现(reproducible numeric encoding & color mapping)
- 自带数据概览、校验、可视化方法(summarization / validation / visualization)
有了这个正式定义,后续的距离计算(distance computation)、聚类(clustering)和可视化(visualization)才能在不同数据集和项目场景之中稳定运行。
常见工作流(Typical Workflow)
- 你的表格应当是一行一个实体(entity,例如个人 individual / 企业 firm / 地区 region / 组织 organization),一列一个时间点(time point)。
示例输入(DataFrame):
| Entity ID | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| 1 | EDU | EDU | FT | FT |
| 2 | EDU | UNEMP | UNEMP | FT |
| 3 | FT | FT | FT | FT |
每一行代表一个人(individual),也就是一条序列(sequence);每一列代表一个时间点(time point)。
注意
预处理阶段建议把时间列名清理成纯数字(1, 2, 3, 4),而不是 Y1–Y4。否则画图时 x 轴会显示 Y1, Y2, Y3, Y4,可读性不如 1–4。如何清理时间列,可参考文档 清理时间列
提供完整且有序的状态列表(states),并按你希望的顺序排列;这个顺序会影响可视化的图例(legend)展示,例如 “Low”、“Medium”、“High”,而不是乱序。
可选:提供一个ID 列(id_col)作为稳定索引,便于聚类与对齐。
初始化
SequenceData,随后可用:values()/to_numeric()给下游算法使用;get_legend()/get_colormap()直接用于绘图。
用法(Function Usage)
仅包含必需参数的最小示例(足以满足大多数用例):
sequence = SequenceData(
data=df,
time=['1','2','3', ...], # 有序时间列
states=['EDU','FT','UNEMP'], # 完整、有序的状态空间
labels=['Education','Full-time','Unemployed'], # 可选显示标签;顺序必须与州一一对应;如果未设置标签,图例将恢复为州名称
id_col='Entity ID', # ID 列;如果缺失,请使用 assign_unique_ids 创建一个
)具有所有可用参数的完整示例(用于高级定制):
sequence = SequenceData(
data=df,
time=['1','2','3', ...], # 有序时间列
states=['EDU','FT','UNEMP'], # 完整、有序的状态空间
labels=['Education','Full-time','Unemployed'], # 可选显示标签;顺序必须与州一一对应;如果未设置标签,图例将恢复为州名称
id_col='Entity ID', # ID 列;如果缺失,请使用 assign_unique_ids 创建一个
weights=None, # 可选(默认每行 1 个)
start=1, # 摘要中使用的起始索引
custom_colors=None # 可选颜色列表
)参数说明(Entry Parameters)
| 参数(Parameter) | 必填(Required) | 类型(Type) | 说明(Description) |
|---|---|---|---|
data | ✓ | DataFrame | 输入数据集,行 = 实体(entities),列 = 时间点(time points)。 |
time | ✓ | list | 按时间顺序排列的时间列名列表。 |
states | ✓ | list | 有序的状态空间(state space),决定编码(encoding)与颜色(colors)。 |
labels | ✗ | list | 人类可读名称(human-readable names),长度与 states 相同。 |
id_col | ✓ | str | 含唯一序列 ID(sequence IDs)的列名;如果没有该列,请在定义序列数据前用 assign_unique_ids 创建。 |
weights | ✗ | ndarray | 行权重(row weights),默认全为 1。 |
start | ✗ | int | 数据概览(summaries)中的起始索引,默认 1。 |
custom_colors | ✗ | list | 用户自定颜色列表(custom color list),长度需与 states 一致。 |
说明
这里的summaries(即在
start的说明里提到的 “summaries”)指在初始化SequenceData之后,通过describe()等内置方法生成的数据概览(例如状态分布、缺失情况、序列长度等)。具体输出示例见下文 Examples。参数start用来设置这些概览里显示的起始索引(比如从 1 开始而不是 0)。
需要记住的关键规则
1. 顺序决定一切
颜色遵循您传入的状态的顺序。如果 states = [1, 2, 3],则第一个颜色映射到状态 1,第二个颜色映射到状态 2,依此类推。在整个项目中保持相同的状态顺序,以保持颜色的一致性。
2. 标签必须是字符串
标签用于图例。如果您传递非字符串标签,Sequenzo 会发出警告。
3. 默认情况下,缺失值会固定为浅灰色
如果您的数据包含缺失单元格,并且您没有包含专门的 “Missing” 状态,SequenceData 会自动将 “Missing” 添加到状态列表中,并将其颜色设置为浅灰色(颜色代码为 #cfcccc)。
如果您提供的 custom_colors 条目比最终状态数少一个(即,您只为非缺失状态着色),该类将自动为您添加灰色。
4. 长度检查
如果您提供 custom_colors 参数,其长度必须与以下任一参数匹配:
- 状态总数(如果您自行添加
"Missing",则包含该参数),或 - 非缺失状态的数量(SequenceData 随后会将缺失状态附加为灰色)。
5. 较长的状态列表
默认情况下,≤20 个状态使用光谱调色板(为了便于阅读,已反转显示),21-40 个状态使用 viridis 调色板,>40 个状态使用组合调色板(viridis + Set3 + tab20)。您可以通过提供 custom_colors 来覆盖其中任何一个。
有关着色的更多详细信息,请参阅此文档.
关键特性(Key Features)
校验(Validation)
- 确认所有
states在数据中可识别。 - 如果提供了
id_col,检查其唯一性(uniqueness)。 - 检查
labels的长度与类型是否正确。 - 校验
weights的长度;未提供时默认全为 1。
缺失值(Missing Values)
- 自动检测 NA 单元格(NA,即缺失值,missing)。
- 如果你没在
states里包含"Missing",但数据里又检测到缺失值,Sequenzo 会自动帮你把"Missing"加进去,这样这些单元格就能被明确标成“缺失”。 - 将缺失单元映射到最后一个整数编码。
- 建议在
states与labels里显式包含"Missing"。
编码与颜色(Encoding & Colors)
- 状态按 用户提供的顺序 映射为整数1...N(其中 N 表示状态总数)。
- 该顺序同时决定:
- 整数编码(integer encoding)
- 色图分配(colormap assignment)
- 图例顺序(legend order)
颜色管理(Color Management)
- 若提供
custom_colors,其长度必须与states对齐;custom_colors是一个列表,元素可写为十六进制颜色代码(hex color code),例如#BD462D。 - 否则将使用 seaborn 的
"Spectral"(≤ 20 个状态)或"cubehelix";为增强对比,默认反转颜色(reversed colors)。
核心属性(Core Attributes)
seq.states、seq.labels→ 标准化的状态空间(canonical state space)。seq.ids→ 实体 ID(entity IDs)。seq.n_sequences→ 序列数量(number of sequences)。seq.n_steps→ 序列长度(sequence length)。seq.weights→ 行权重(row weights,NumPy array)。
关键方法(Key Methods)
| 方法(Method) | 返回值(Returns) | 说明(Description) |
|---|---|---|
get_colormap() | ListedColormap | 与编码 1...N 对齐的色图(colormap)。 |
get_legend() | (handles, labels) | 预构建的绘图图例元素与标签。 |
describe() | 打印数据集的缺失值概览。 | |
plot_legend() | figure | 渲染或保存状态图例。 |
说明
我们列出了 关键属性(Key attributes)和 关键方法(Key methods),但多数情况下你不需要手动调用。初始化并运行SequenceData()之后,系统会自动打印整体验证与概要信息(summary)。这些属性与方法主要用于:
- 查看细节(如缺失情况、编码、权重);
- 绘图辅助(比如需要图例或色图时,用
get_legend()/get_colormap());- 导出数据给下游算法(用
to_numeric()/to_dataframe())
示例(Examples)
1)最简构造(含缺失值)(Minimal Construction with Missing Values)
# 创建 SequenceData 对象(Create a SequenceData object)
# 定义时间跨度列(time-span)
time_list = list(df.columns)[1:]
# 为了便于阅读与解释,我们使用 'D1 (Very Low)'、'D10 (Very High)' 这类命名。
# 注意:states 的顺序会影响编码与图例(legend)顺序。
# states = ['Very Low', 'Low', 'Middle', 'High', 'Very High']
states = ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9']
sequence_data = SequenceData(
df,
time=time_list,
id_col="country",
states=states,
labels=states # labels 的元素顺序需与 states 一一对应;如未设置 labels,图例会显示 states 的名称
)
sequence_data输出(Output):
[!] Detected missing values (empty cells) in the sequence data.
→ Automatically added 'Missing' to `states` and `labels` for compatibility.
However, it's strongly recommended to manually include it when defining `states` and `labels`.
For example:
states = ['At Home', 'Left Home', 'Missing']
labels = ['At Home', 'Left Home', 'Missing']
This ensures consistent color mapping and avoids unexpected visualization errors.
[>] SequenceData initialized successfully! Here's a summary:
[>] Number of sequences: 194
[>] Number of time points: 223
[>] Min/Max sequence length: 216 / 223
[>] There are 7 missing values across 1 sequences.
First few missing sequence IDs: ['Panama'] ...
[>] Top sequences with the most missing time points:
(Each row shows a sequence ID and its number of missing values)
Missing Count
Sequence ID
Panama 7
[>] States: ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'Missing']
[>] Labels: ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'Missing']
SequenceData(194 sequences, States: ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'Missing'])2. 如果缺少 ID,先补上(Add IDs If Missing)
from sequenzo.utils import assign_unique_ids
df = assign_unique_ids(df, id_col_name='Entity ID')
seq = SequenceData(
df,
time=year_cols,
states=states,
id_col='Entity ID'
)代码:梁彧祺
文档:梁彧祺
编辑:梁彧祺
翻译:明煜坤,曲思竹