Datasets documentation
加载 TsFile 数据
加载 TsFile 数据
TsFile 是一种专为时间序列数据设计的列式文件格式,用作 Apache IoTDB 的原生存储层。与 Parquet 等通用列式格式相比,TsFile 感知时间序列数据模型(时间戳、设备和测量值),并维护一个内部时间索引,从而支持在不扫描整个文件的情况下进行时间范围裁剪。
由于该加载器不遵循常规的“每行一条记录”的表格约定,因此我们将其作为单独的指南提供:每个输出行对应一个 device,而每次测量的值则以 Arrow list<...> 列的形式返回。具体映射关系将在下文详细说明。
安装
加载器依赖于 tsfile Python 包:
pip install "tsfile>=2.3.0"数据模型和输出布局
加载器遵循 TsFile 的 表模型。每个表的列是以下之一:
- TAG — a string-typed identifier; the tuple of TAG values uniquely identifies a device (i.e. a single time-series source).
- FIELD — 值随时间演化的测量值。
- TIME — 时间戳列,默认命名为
time。
加载器为每个设备输出一行数据集。在每一行中,time 列和所有 FIELD 列均为 Arrow list<...> 列,包含该设备的完整时间序列,并按时间升序排列。TAG 列则显示为标量 string 列。
具体来说,输出模式的形式为:
<tag_1>: string <tag_2>: string # one column per TAG ... time: list<timestamp[unit, tz]> <field_1>: list<original_type> # one column per FIELD <field_2>: list<original_type> ...
当同一设备出现在拆分(split)的多个输入文件中时,其按文件划分的分块(chunks)会先按时间戳排序并拼接,然后作为单行输出。同一设备出现重复时间戳时会引发 ValueError。
基本用法
加载单个 TsFile:
>>> from datasets import load_dataset
>>> dataset = load_dataset("tsfile", data_files="my_data.tsfile")显式地将文件映射到拆分:
>>> dataset = load_dataset(
... "tsfile",
... data_files={"train": "train_data.tsfile", "test": "test_data.tsfile"},
... )Hub 上的示例数据集
在 tsfile/lotsa_data 中提供了一个可直接使用的示例。由于 .tsfile 文件会被自动识别,因此您可以直接通过仓库 ID 加载它,而无需指定 data_files:
>>> from datasets import load_dataset
>>> dataset = load_dataset("tsfile/lotsa_data")
>>> dataset
DatasetDict({
train: Dataset({
features: ['timeseries_id', 'time', 'value'],
num_rows: 91
})
})每一行代表一个设备。timeseries_id 列中的 TAG 用于标识设备,而 time 和 value 是 list<...> 列,保存该设备的完整时间序列:
>>> row = dataset["train"][0]
>>> row["timeseries_id"]
'Bear_assembly_Angel'
>>> len(row["time"]), len(row["value"])
(8760, 8760)
>>> row["time"][:3]
[datetime.datetime(2017, 1, 1, 0, 0), datetime.datetime(2017, 1, 1, 1, 0), datetime.datetime(2017, 1, 1, 2, 0)]选择表格
TsFile 可以包含多个表。当省略 table_name 时,将使用第一个有效文件中找到的第一个表。查找操作不区分大小写。
>>> dataset = load_dataset("tsfile", data_files="my_data.tsfile", table_name="sensor_data")选择列
columns 限制所读取的 FIELD 列。TAG 列和 time 列始终会返回,因为它们用于标识设备及其时间线。columns 中指向 TAG 或 time 列的名称会被静默忽略(它们仍会照常输出,仅一次);与所有文件中均不存在的字段相匹配的名称将变为全为 null 的列表列。
>>> dataset = load_dataset(
... "tsfile",
... data_files="my_data.tsfile",
... columns=["temperature", "humidity"],
... )按时间范围筛选
start_time 和 end_time 为包含边界;两者均可省略。这些边界会下推至 TsFile 的内部时间索引,因此仅从磁盘读取匹配的数据块。两个边界均接受以下任意一种:
int—timestamp_unit中的原始纪元(默认单位为毫秒);datetime.datetime— 无时区信息的值被视为 UTC,带时区信息的值会被转换为 UTC;datetime.date;- ISO-8601
str,例如"2024-01-01T00:00:00"; pyarrow.TimestampScalar.
>>> from datetime import datetime
>>> dataset = load_dataset(
... "tsfile",
... data_files="my_data.tsfile",
... start_time=datetime(2023, 11, 14),
... end_time="2023-11-15T00:00:00",
... )跨文件的模式演进
当不同文件暴露不同的列时——例如后续引入了新的传感器字段——加载器会取所有 FIELD 列的并集,并用 null 填充缺失值。数值型 FIELD 类型将按照 IoTDB 的加宽规则进行提升(INT32 → INT64 → DOUBLE、INT32 → FLOAT → DOUBLE)。
>>> dataset = load_dataset("tsfile", data_files=["day1.tsfile", "day2.tsfile"])处理无法读取的文件
默认情况下,无法读取或非 TsFile 的输入会引发错误。将 on_bad_files 设置为 "warn" 以记录日志并继续,或设置为 "skip" 以静默丢弃该文件。
>>> dataset = load_dataset("tsfile", data_files="data/*.tsfile", on_bad_files="skip")时间戳单位和时区
timestamp_unit(默认值为 "ms",与 IoTDB 保持一致)控制 time 列的分辨率以及整数时间边界的解释方式。timestamp_tz 为 Arrow 时间戳类型附加时区;None(默认值)将生成无时区类型。
>>> dataset = load_dataset(
... "tsfile",
... data_files="my_data.tsfile",
... timestamp_unit="us",
... timestamp_tz="UTC",
... )内存与批处理
两个参数控制内存使用:
input_batch_size(默认值65_536)—— 从TsFileReader.query_table中每个 Arrow 批次获取的最大行数。用于在流式处理单个设备时限制峰值内存。output_batch_size(默认值为32)— 提供给写入器的每个 Arrow 记录批次中包含的设备数量。较小的值可提供更及时的进度报告;较大的值可降低每个批次的开销。
>>> dataset = load_dataset(
... "tsfile",
... data_files="large_data.tsfile",
... input_batch_size=32_768,
... output_batch_size=128,
... )峰值内存受单个设备在拆分中承载的数据量限制,而非受整个拆分的规模限制。
有关完整参数列表,请参阅 TsFileConfig。
Update on GitHub