Skip to main content

dtflow

PyPI version License pypi downloads

简洁的数据格式转换工具,专为机器学习训练数据设计。

安装

pip install dtflow

# 可选依赖
pip install tiktoken          # Token 统计(OpenAI 模型)
pip install transformers      # Token 统计(HuggingFace 模型)
pip install datasets          # HuggingFace Dataset 转换

🤖 Claude Code 集成

dtflow 内置了 Claude Code skill:

dt install-skill      # 安装 skill
dt skill-status       # 查看状态

安装后在 Claude Code 中输入 /dtflow,Claude 将掌握 dtflow 的完整用法,可直接协助你完成数据处理任务。

快速开始

from dtflow import DataTransformer

# 加载数据
dt = DataTransformer.load("data.jsonl")

# 链式操作:过滤 -> 转换 -> 保存
(dt.filter(lambda x: x.score > 0.8)
   .to(lambda x: {"q": x.question, "a": x.answer})
   .save("output.jsonl"))

核心功能

数据加载与保存

# 支持 JSONL/NDJSON、JSON、CSV/TSV、Parquet、Arrow、Excel(使用 Polars 引擎,比 Pandas 快 3x)
dt = DataTransformer.load("data.jsonl")
dt.save("output.jsonl")

# 从列表创建
dt = DataTransformer([{"q": "问题", "a": "答案"}])

数据过滤

# Lambda 过滤
dt.filter(lambda x: x.score > 0.8)

# 支持属性访问
dt.filter(lambda x: x.language == "zh")

数据验证

# 简单验证,返回不通过的记录列表
errors = dt.validate(lambda x: len(x.messages) >= 2)

if errors:
    for e in errors[:5]:
        print(f"第 {e.index} 行: {e.error}")

Schema 验证

使用 Schema 进行结构化数据验证:

from dtflow import Schema, Field, openai_chat_schema

# 使用预设 Schema
result = dt.validate_schema(openai_chat_schema)
print(result)  # ValidationResult(valid=950, invalid=50, errors=[...])

# 自定义 Schema
schema = Schema({
    "messages": Field(type="list", required=True, min_length=1),
    "messages[*].role": Field(type="str", choices=["user", "assistant", "system"]),
    "messages[*].content": Field(type="str", min_length=1),
    "score": Field(type="float", min=0, max=1),
})

result = dt.validate_schema(schema)

# 过滤出有效数据
valid_dt = dt.validate_schema(schema, filter_invalid=True)
valid_dt.save("valid.jsonl")

预设 Schema

Schema 名称 用途
openai_chat_schema OpenAI messages 格式验证
alpaca_schema Alpaca instruction/output 格式
sharegpt_schema ShareGPT conversations 格式
dpo_schema DPO prompt/chosen/rejected 格式

Field 参数

参数 说明 示例
type 类型验证 "str", "int", "float", "bool", "list", "dict"
required 是否必填 True / False
min / max 数值范围 min=0, max=1
min_length / max_length 长度范围 min_length=1
choices 枚举值 choices=["user", "assistant"]
pattern 正则匹配 pattern=r"^\d{4}-\d{2}-\d{2}$"
custom 自定义验证 custom=lambda x: x > 0

数据转换

# 自定义转换
dt.to(lambda x: {"question": x.q, "answer": x.a})

# 使用预设模板
dt.to(preset="openai_chat", user_field="q", assistant_field="a")

预设模板

预设名称 输出格式
openai_chat {"messages": [{"role": "user", ...}, {"role": "assistant", ...}]}
alpaca {"instruction": ..., "input": ..., "output": ...}
sharegpt {"conversations": [{"from": "human", ...}, {"from": "gpt", ...}]}
dpo_pair {"prompt": ..., "chosen": ..., "rejected": ...}
simple_qa {"question": ..., "answer": ...}

Token 统计

from dtflow import count_tokens, token_counter, token_filter, token_stats

# 计算 token 数量
count = count_tokens("Hello world", model="gpt-4")

# 添加 token_count 字段
dt.transform(token_counter("text")).save("with_tokens.jsonl")

# 按 token 长度过滤
dt.filter(token_filter("text", max_tokens=2048))
dt.filter(token_filter(["question", "answer"], min_tokens=10, max_tokens=4096))

# 统计 token 分布
stats = token_stats(dt.data, "text")
# {"total_tokens": 12345, "avg_tokens": 123, "min_tokens": 5, "max_tokens": 500, ...}

支持 tiktoken(OpenAI,默认)和 transformers 后端,自动检测

# OpenAI 模型 -> 自动使用 tiktoken
count_tokens("Hello", model="gpt-4")

# HuggingFace/本地模型 -> 自动使用 transformers
count_tokens("Hello", model="Qwen/Qwen2-7B")
count_tokens("Hello", model="/home/models/qwen")

Messages Token 统计

专为多轮对话设计的 token 统计功能:

from dtflow import messages_token_counter, messages_token_filter, messages_token_stats

# 为每条数据添加 token 统计
dt.transform(messages_token_counter(model="gpt-4"))  # 简单模式,输出总数
dt.transform(messages_token_counter(model="gpt-4", detailed=True))  # 详细模式
# 详细模式输出: {"total": 500, "user": 200, "assistant": 280, "system": 20, "turns": 5, ...}

# 按 token 数和轮数过滤
dt.filter(messages_token_filter(min_tokens=100, max_tokens=4096))
dt.filter(messages_token_filter(min_turns=2, max_turns=10))

# 统计整个数据集
stats = messages_token_stats(dt.data, model="gpt-4")
# {"count": 1000, "total_tokens": 500000, "user_tokens": 200000, "assistant_tokens": 290000, ...}

格式转换器

from dtflow import (
    to_hf_dataset, from_hf_dataset,    # HuggingFace Dataset
    to_openai_batch, from_openai_batch, # OpenAI Batch API
    to_llama_factory,                   # LLaMA-Factory Alpaca 格式
    to_axolotl,                         # Axolotl 格式
    messages_to_text,                   # messages 转纯文本
)

# HuggingFace Dataset 互转
ds = to_hf_dataset(dt.data)
ds.push_to_hub("my-dataset")

data = from_hf_dataset("tatsu-lab/alpaca", split="train")

# OpenAI Batch API
batch_input = dt.to(to_openai_batch(model="gpt-4o"))
results = from_openai_batch(batch_output)

# messages 转纯文本(支持 chatml/llama2/simple 模板)
dt.transform(messages_to_text(template="chatml"))

LLaMA-Factory 格式

完整支持 LLaMA-Factory 的 SFT 训练格式:

from dtflow import (
    to_llama_factory,              # Alpaca 格式(单轮)
    to_llama_factory_sharegpt,     # ShareGPT 格式(多轮对话)
    to_llama_factory_vlm,          # VLM Alpaca 格式
    to_llama_factory_vlm_sharegpt, # VLM ShareGPT 格式
)

# Alpaca 格式
dt.transform(to_llama_factory()).save("alpaca.jsonl")
# 输出: {"instruction": "...", "input": "", "output": "..."}

# ShareGPT 格式(多轮对话)
dt.transform(to_llama_factory_sharegpt()).save("sharegpt.jsonl")
# 输出: {"conversations": [{"from": "human", "value": "..."}, {"from": "gpt", "value": "..."}], "system": "..."}

# VLM 格式(图片/视频)
dt.transform(to_llama_factory_vlm(images_field="images")).save("vlm.jsonl")
# 输出: {"instruction": "...", "output": "...", "images": ["/path/to/img.jpg"]}

dt.transform(to_llama_factory_vlm_sharegpt(images_field="images", videos_field="videos"))
# 输出: {"conversations": [...], "images": [...], "videos": [...]}

ms-swift 格式

支持 ModelScope ms-swift 的训练格式:

from dtflow import (
    to_swift_messages,        # 标准 messages 格式
    to_swift_query_response,  # query-response 格式
    to_swift_vlm,             # VLM 格式
)

# messages 格式
dt.transform(to_swift_messages()).save("swift_messages.jsonl")
# 输出: {"messages": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}

# query-response 格式(自动提取 history)
dt.transform(to_swift_query_response(query_field="messages")).save("swift_qr.jsonl")
# 输出: {"query": "...", "response": "...", "system": "...", "history": [["q1", "a1"], ...]}

# VLM 格式
dt.transform(to_swift_vlm(images_field="images")).save("swift_vlm.jsonl")
# 输出: {"messages": [...], "images": ["/path/to/img.jpg"]}

训练框架一键导出

将数据导出为目标训练框架可直接使用的格式,自动生成配置文件:

from dtflow import DataTransformer

dt = DataTransformer.load("data.jsonl")

# 1. 检查框架兼容性
result = dt.check_compatibility("llama-factory")
print(result)
# ✅ 兼容 - LLaMA-Factory (openai_chat)
# 或
# ❌ 不兼容 - 错误: xxx

# 2. 一键导出到 LLaMA-Factory
files = dt.export_for("llama-factory", "./llama_ready/")
# 生成文件:
# - ./llama_ready/custom_dataset.json      # 数据文件
# - ./llama_ready/dataset_info.json        # 数据集配置
# - ./llama_ready/train_args.yaml          # 训练参数模板

# 3. 导出到 ms-swift
files = dt.export_for("swift", "./swift_ready/")
# 生成: data.jsonl + train_swift.sh

# 4. 导出到 Axolotl
files = dt.export_for("axolotl", "./axolotl_ready/")
# 生成: data.jsonl + config.yaml

# 指定数据集名称
dt.export_for("llama-factory", "./output/", dataset_name="my_sft_data")

支持的框架

框架 导出内容 使用方式
llama-factory data.json + dataset_info.json + train_args.yaml llamafactory-cli train train_args.yaml
swift data.jsonl + train_swift.sh bash train_swift.sh
axolotl data.jsonl + config.yaml accelerate launch -m axolotl.cli.train config.yaml

自动格式检测

检测到的格式 数据结构
openai_chat {"messages": [{"role": "user", ...}]}
alpaca {"instruction": ..., "output": ...}
sharegpt {"conversations": [{"from": "human", ...}]}
dpo {"prompt": ..., "chosen": ..., "rejected": ...}

其他操作

# 采样
dt.sample(100)           # 随机采样 100 条
dt.head(10)              # 前 10 条
dt.tail(10)              # 后 10 条

# 分割
train, test = dt.split(ratio=0.8, shuffle=True, seed=42)

# 统计
stats = dt.stats()       # 总数、字段信息
count = dt.count(lambda x: x.score > 0.9)

# 打乱
dt.shuffle(seed=42)

CLI 命令

# 数据采样
dt sample data.jsonl --num=10
dt sample data.csv --num=100 --sample_type=head
dt sample data.jsonl 1000 --by=category           # 分层采样
dt sample data.jsonl 1000 --by=meta.source        # 按嵌套字段分层采样
dt sample data.jsonl 1000 --by=messages.#         # 按消息数量分层采样
dt sample data.jsonl --where="category=tech"      # 筛选后采样
dt sample data.jsonl --where="messages.#>=2"      # 多条件筛选

# 交互式浏览(表格 + 详情联动 TUI,需交互式终端)
dt view data.jsonl                                # 打开浏览器,按 ? 看快捷键
dt view data.csv                                  # CSV/Parquet 等表格数据
dt view data.jsonl --format=dpo                   # 强制按指定格式渲染详情
dt view big.jsonl --cap=50000                     # 提高大文件加载上限(默认 1 万行)
dt view data.jsonl --sort=-chars                  # 启动即全量排序(最长的排前面)
dt view data.jsonl --where="turns>=6" --search=报错 # 启动即筛选 + 搜索(可多个 --where)

# 静态预览(--pretty 走格式感知渲染:对话气泡/dpo对比/alpaca分段/表格)
dt head data.jsonl --pretty                       # 前 N 条,格式化渲染
dt sample data.jsonl --pretty                     # 采样 + 格式化渲染

# 按行范围查看(Python 切片语法)
dt slice data.jsonl 10:20                          # 第 10-19 行(0-based,左闭右开)
dt slice data.jsonl :100                           # 前 100 行
dt slice data.jsonl 100:                           # 第 100 行到末尾
dt slice data.jsonl 10:20 -o sliced.jsonl          # 保存到文件
dt slice data.jsonl 10:20 -f question,answer       # 只显示指定字段

# 数据转换 - 预设模式
dt transform data.jsonl --preset=openai_chat
dt transform data.jsonl --preset=alpaca

# 数据转换 - 配置文件模式
dt transform data.jsonl                    # 首次运行生成配置文件
# 编辑 .dt/data.py 后再次运行
dt transform data.jsonl --num=100          # 执行转换

# Pipeline 执行(可复现的数据处理流程)
dt run pipeline.yaml
dt run pipeline.yaml --input=new_data.jsonl --output=result.jsonl

# Token 统计
dt token-stats data.jsonl --field=messages --model=gpt-4
dt token-stats data.jsonl --field=messages[-1].content   # 统计最后一条消息
dt token-stats data.jsonl --field=text --detailed
dt token-stats data.jsonl --workers=4                    # 多进程加速(数据量大时自动启用)

# 数据对比
dt diff v1/train.jsonl v2/train.jsonl
dt diff a.jsonl b.jsonl --key=id
dt diff a.jsonl b.jsonl --key=meta.uuid    # 按嵌套字段匹配

# 数据清洗
dt clean data.jsonl --drop-empty                    # 删除任意空值记录
dt clean data.jsonl --drop-empty=text,answer        # 删除指定字段为空的记录
dt clean data.jsonl --drop-empty=meta.source        # 删除嵌套字段为空的记录
dt clean data.jsonl --min-len=text:10               # text 字段最少 10 字符
dt clean data.jsonl --min-len=messages.#:2          # 至少 2 条消息
dt clean data.jsonl --max-len=messages[-1].content:500  # 最后一条消息最多 500 字符
dt clean data.jsonl --keep=question,answer          # 只保留这些字段
dt clean data.jsonl --drop=metadata                 # 删除指定字段
dt clean data.jsonl --strip                         # 去除字符串首尾空白
dt clean data.jsonl --min-tokens=content:10          # 最少 10 tokens
dt clean data.jsonl --max-tokens=content:1000        # 最多 1000 tokens
dt clean data.jsonl --min-tokens=text:50 -m gpt-4    # 指定分词器

# 数据去重
dt dedupe data.jsonl                            # 全量精确去重
dt dedupe data.jsonl --key=text                 # 按字段精确去重
dt dedupe data.jsonl --key=meta.id              # 按嵌套字段去重
dt dedupe data.jsonl --key=messages[0].content  # 按第一条消息内容去重
dt dedupe data.jsonl --key=text --similar=0.8   # 相似度去重

# 数据集切分
dt split data.jsonl --ratio=0.8 --seed=42           # 二分: train/test
dt split data.jsonl --ratio=0.7,0.15,0.15           # 三分: train/val/test
dt split data.jsonl --ratio=0.8 -o /tmp/output      # 指定输出目录

# 训练框架导出
dt export data.jsonl --framework=llama-factory       # 导出到 LLaMA-Factory
dt export data.jsonl -f swift -o ./swift_out         # 导出到 ms-swift
dt export data.jsonl -f axolotl                      # 导出到 Axolotl
dt export data.jsonl -f llama-factory --check        # 仅检查兼容性

# 文件拼接
dt concat a.jsonl b.jsonl -o merged.jsonl

# 数据统计
dt stats data.jsonl                                       # 快速模式
dt stats data.jsonl --full                                # 完整模式(含值分布)
dt stats data.jsonl --full --field=category               # 指定字段统计
dt stats data.jsonl --full --expand=tags                  # 展开 list 字段统计元素分布
dt stats data.jsonl --full --expand='messages[*].role'    # 展开嵌套 list 字段

# Claude Code Skill 安装
dt install-skill                              # 安装到 ~/.claude/skills/
dt skill-status                               # 查看安装状态

# 数据验证
dt validate data.jsonl --preset=openai_chat           # 使用预设 schema 验证
dt validate data.jsonl --preset=alpaca --verbose      # 详细输出
dt validate data.jsonl --preset=sharegpt --filter-invalid -o valid.jsonl  # 过滤出有效数据
dt validate data.jsonl --preset=dpo --max-errors=100  # 限制错误输出数量
dt validate data.jsonl --preset=openai_chat --workers=4  # 多进程加速

交互式数据浏览 (dt view)

dt view <file> 打开一个 master-detail 终端浏览器,专为查看训练数据设计:上方表格扫视样本(派生列 turns/roles/first_user/chars + 元数据),下方详情按格式渲染当前行(对话气泡按 role 上色、代码块高亮;dpo 对比;alpaca 分段;通用数据全展开)——无需逐层展开。大文件走窗口化加载(--cap,默认 1 万行)。

按键 功能
↑/↓ j/k 选行(详情联动)
PgUp/PgDn 整页 · d/u(或 Ctrl+d/u) 半屏
g/G 首/末行 · Tab 切焦点滚动长对话
←/→ h/l 水平滚动表格
s 全量排序(输入列名,加 - 反向,如 -chars):扫全文件,跨窗口有效
/ f 全量搜索/筛选/ 搜整条记录(含 assistant 回复,re: 前缀走正则)、f where——扫描整个文件(带进度,Esc 取消),命中聚成可分页子集;r 清除
F / 点列头 列值勾选筛选(Excel AutoFilter 式):列出该列唯一值+频次,顶部搜索框按子串过滤候选值,勾选保留哪些 → 子集
n/N * 详情内逐字段导航(对话按条走 msg0/msg1…);* 只在含搜索命中的字段间跳
w 导出当前子集(或 v 选区)到文件,按扩展名定格式;同时写血缘
C 复制「复现当前视图」的 dt view 命令到剪贴板
S 列快照:某列的 n·min·max·mean·非空率(当前浏览序列;完整分布用 dt stats
c 选列(勾选面板,同时作用于表格列与详情字段)
y v 复制当前样本 JSON · v 多选后 y 复制多条
Enter 放大当前样本(Esc 返回)· z 上下/左右布局 · +/- 调整分区
? 帮助 · q 退出

搜索/筛选/排序都是全量的、且可叠加/fFs 一律扫描整个文件而非仅当前窗口,得到的全局行号序列即新的浏览序列(翻窗口不失效),状态栏显示「命中 M/N (占比%)」。三类约束各占独立槽位:/ 一个(新搜索覆盖旧的)、f 可反复叠加(多条之间是 and,用来表达无括号语法写不出的 (a or b) and (c or d))、F 按列独立记「保留值集」故可反复调整/加回。r 一键清空全部。

/ 搜的是整条记录的每个值(不只是表格列——表格列只是派生摘要,first_user 只是第一条用户消息,靠列搜会把 assistant 回复整个漏掉),命中处在表格与详情里画黄底,* 逐个跳过去。

闭环到落地:筛出来的子集用 w 导出成文件(.jsonl 流式写,几十万行不占内存;其他扩展名走 save_data 分派),导出时自动写血缘 sidecar,dt history <out> 能查到来源文件与当时的全部条件。C 把当前视图翻译回一条 dt view ... --where=... --search=... --sort=... 命令——粘回终端即还原(多列值筛选翻译成多条 --where,含特殊字符的值无法安全嵌入时会明说,完整条件以血缘为准)。

查看数据时的即时筛选归 view;完整分布统计(直方图/分位数/value_counts/token)归 dt stats / dt token-stats

坏行(非法 JSON)不会拦住浏览dt view 把它显示成一条占位行(_parse_error / _raw_line 两列),行号不错位,还能用 / 直接把坏行搜出来定位——语法坏掉的行恰恰是你打开浏览器要找的东西。其他命令按「会不会写出新文件」区别对待:head/tail/sample 跳过但在 stderr 报出第几行,clean/transform 等直接抛错(附行号与行内容),不静默丢数据。

f 筛选语法列名 运算符 值,列名直接用表头看到的名字(派生列 chars/turns/roles、元数据列 source 等;深层字段仍可写 messages.#>=2)。运算符 > >= < <= == != =~=(包含子串,不区分大小写)。多列用 and/or 组合and 优先级高于 or),如 turns>=6 and chars<2000。派生列名自动按该列的值比较,其余当真实字段路径。

按内容包含筛选first_user~=退款(派生列,匹配全文而非表格里那 80 字预览)、source~=alpacamessages[0].content~=报错(深层路径)、messages[*].content:join~=关键词(搜整段对话,:join 不可省——不加时 [*] 只取第一个元素)。~=///值面板搜索框三个入口都不区分大小写;要区分用 ==

格式自动检测:openai_chat / sharegpt / dpo / alpaca / generic(CSV 等表格数据全部列展示)。--format 可强制指定。

dt head/sample/tail/slice--pretty 复用同一套渲染,做静态一次性预览(可管道时自动降级为 ndjson,agent 友好)。

字段路径语法

CLI 命令中的字段参数支持嵌套路径语法,可访问深层嵌套的数据:

语法 含义 示例
a.b.c 嵌套字段 meta.source
a[0].b 数组索引 messages[0].role
a[-1].b 负索引 messages[-1].content
a.# 数组长度 messages.#
a[*].b 展开所有元素 messages[*].role
a[*].b:join 展开并用 | 拼接 messages[*].role:join
a[*].b:unique 展开去重后拼接 messages[*].role:unique

支持字段路径的命令参数:

命令 参数 示例
sample --by=, --where= --by=meta.source--where=messages.#>=2
dedupe --key= --key=meta.id--key=messages[0].content
clean --drop-empty= --drop-empty=meta.source
clean --min-len= --min-len=messages.#:2
clean --max-len= --max-len=messages[-1].content:500
clean --min-tokens= --min-tokens=content:10
clean --max-tokens= --max-tokens=content:1000
token-stats --field= --field=messages[-1].content
diff --key= --key=meta.uuid

--where 支持的操作符:

操作符 含义 示例
= 等于 --where="category=tech"
!= 不等于 --where="source!=wiki"
~= 包含(不区分大小写) --where="content~=机器学习"
> 大于 --where="score>0.8"
>= 大于等于 --where="messages.#>=2"
< 小于 --where="length<1000"
<= 小于等于 --where="turns<=10"

示例数据:

{"meta": {"source": "wiki"}, "messages": [{"role": "user", "content": "hi"}, {"role": "assistant", "content": "hello"}]}
  • meta.source"wiki"
  • messages[0].role"user"
  • messages[-1].content"hello"
  • messages.#2
  • messages[*].role"user" (默认取第一个)
  • messages[*].role:join"user|assistant"

Pipeline 配置

使用 YAML 配置文件定义可复现的数据处理流程:

# pipeline.yaml
version: "1.0"
seed: 42
input: raw_data.jsonl
output: processed.jsonl

steps:
  - type: filter
    condition: "score > 0.5"

  - type: filter
    condition: "len(text) > 10"

  - type: transform
    preset: openai_chat
    params:
      user_field: q
      assistant_field: a

  - type: dedupe
    key: text

支持的步骤类型:

步骤 参数 说明
filter condition 条件过滤:score > 0.5, len(text) > 10, field is not empty
transform preset, params 格式转换,使用预设模板
dedupe key, similar 去重,支持精确和相似度去重
sample num, seed 随机采样
head num 取前 N 条
tail num 取后 N 条
shuffle seed 打乱顺序
split ratio, seed 数据集分割

执行 Pipeline:

dt run pipeline.yaml
dt run pipeline.yaml --input=new_data.jsonl  # 覆盖输入文件

数据血缘追踪

记录数据处理的完整历史,支持可复现和问题追溯:

# 启用血缘追踪
dt = DataTransformer.load("raw.jsonl", track_lineage=True)

# 正常进行数据处理
result = (dt
    .filter(lambda x: x.score > 0.5)
    .transform(lambda x: {"q": x.q, "a": x.a})
    .dedupe("q")
)

# 保存时记录血缘
result.save("processed.jsonl", lineage=True)
# 自动生成 processed.jsonl.lineage.json

查看血缘历史:

dt history processed.jsonl
# 输出:
# 📊 数据血缘报告: processed.jsonl
# └─ 版本 1
#    来源: raw.jsonl
#    操作链:
#      ├─ filter: 1000 → 800
#      ├─ transform: 800 → 800
#      └─ dedupe: 800 → 750
#    输出数量: 750

dt history processed.jsonl --json  # JSON 格式输出

日志查看

dtflow 内置了 toolong 日志查看器:

pip install dtflow[logs]    # 安装日志工具

tl app.log                  # 交互式 TUI 查看
tl --tail app.log           # 实时跟踪(类似 tail -f)
dt logs                     # 查看使用说明

大文件流式处理

专为超大文件设计的流式处理接口,内存占用 O(1),支持 JSONL/NDJSON、CSV/TSV、Parquet、Arrow 格式:

from dtflow import load_stream, load_sharded

# 流式加载和处理(100GB 文件也只用常量内存)
(load_stream("huge_100gb.jsonl")
    .filter(lambda x: x["score"] > 0.5)
    .transform(lambda x: {"text": x["content"]})
    .save("output.jsonl"))

# 跨格式转换(CSV → Parquet)
(load_stream("data.csv")
    .filter(lambda x: x["score"] > 0.5)
    .save("output.parquet"))

# 分片文件加载(支持多格式)
(load_sharded("data/train_*.parquet")
    .filter(lambda x: len(x["text"]) > 10)
    .save("merged.jsonl"))

# 分片保存
(load_stream("huge.jsonl")
    .transform(lambda x: {"q": x["question"], "a": x["answer"]})
    .save_sharded("output/", shard_size=100000))
# 生成: output/part-00000.jsonl, output/part-00001.jsonl, ...

# 批次处理(适合需要批量调用 API 的场景)
for batch in load_stream("data.jsonl").batch(1000):
    results = call_api(batch)  # 批量处理

特点:

  • 惰性执行:filter/transform 不会立即执行,只在 save/collect 时才触发
  • O(1) 内存:无论文件多大,内存占用恒定(读取侧)
  • 多格式支持:JSONL/NDJSON、CSV/TSV、Parquet、Arrow 均支持流式处理
  • 跨格式转换:可直接从 CSV 读取并保存为 Parquet 等
  • 分片支持:支持 glob 模式加载多个分片,自动合并处理

错误处理

# 跳过错误项(默认)
dt.to(transform_func, on_error="skip")

# 抛出异常
dt.to(transform_func, on_error="raise")

# 保留原始数据
dt.to(transform_func, on_error="keep")

# 返回错误信息
result, errors = dt.to(transform_func, return_errors=True)

设计哲学

函数式优于类继承

不需要复杂的 OOP 抽象,直接用函数解决问题:

# ✅ 简单直接
dt.to(lambda x: {"q": x.question, "a": x.answer})

# ❌ 不需要这种设计
class MyFormatter(BaseFormatter):
    def format(self, item): ...

预设是便利层,不是核心抽象

90% 的需求用 transform(lambda x: ...) 就能解决。预设只是常见场景的快捷方式:

# 预设:常见场景的便利函数
dt.to(preset="openai_chat")

# 自定义:完全控制转换逻辑
dt.to(lambda x: {
    "messages": [
        {"role": "user", "content": x.q},
        {"role": "assistant", "content": x.a}
    ]
})

KISS 原则

  • 一个核心类 DataTransformer 搞定所有操作
  • 链式 API,代码像自然语言
  • 属性访问 x.field 代替 x["field"]
  • 不过度设计,不追求"可扩展框架"

实用主义

不追求学术上的完美抽象,只提供足够好用的工具

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dtflow-0.7.1.tar.gz (262.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dtflow-0.7.1-py3-none-any.whl (196.7 kB view details)

Uploaded Python 3

File details

Details for the file dtflow-0.7.1.tar.gz.

File metadata

  • Download URL: dtflow-0.7.1.tar.gz
  • Upload date:
  • Size: 262.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dtflow-0.7.1.tar.gz
Algorithm Hash digest
SHA256 6da6eb94becc88824d3667b7f6cea93307030456fb11de75da4e4e22ef74b43b
MD5 3cd4e64250fa4410e436d4fae0ae0fff
BLAKE2b-256 0183888557e089a56b4688bd10216e7771409ac7061d247e7f99049d764e6dc1

See more details on using hashes here.

Provenance

The following attestation bundles were made for dtflow-0.7.1.tar.gz:

Publisher: python-publish.yml on KenyonY/dtflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dtflow-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: dtflow-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 196.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for dtflow-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b6dd80b8c58a552a996dcbcb3ef1c1a992a7f59130a6a68f32e314386067bf0b
MD5 7e323c2c5c0a887844a425f8714cdc02
BLAKE2b-256 6fa7885849548b6e777ef15b141ed50a5966f75b8b35730a7818e4734ee74a77

See more details on using hashes here.

Provenance

The following attestation bundles were made for dtflow-0.7.1-py3-none-any.whl:

Publisher: python-publish.yml on KenyonY/dtflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.7.6

2 files

0.7.5

2 files

0.7.4

2 files

0.7.3

2 files

0.7.2

2 files

This release

0.7.1 This release

2 files

0.7.0

2 files

0.6.12

2 files

0.6.11

2 files

0.6.10

2 files

0.6.9

2 files

0.6.8

2 files

0.6.7

2 files

0.6.5

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.14

2 files

0.5.13

2 files

0.5.12

2 files

0.5.11

2 files

0.5.10

2 files

0.5.9

2 files

0.5.8

2 files

0.5.7

2 files

0.5.6

2 files

0.5.5

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.0

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.6

2 files

0.1.5

2 files

0.1.3

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page