Dataiku DSS Prepare recipe:数据清洗与准备实战精讲
Dataiku DSS 里最被低估的步骤Prepare recipe 到底怎么准备数据做数据项目这些年我有个特别深的体会一个模型最终能跑出什么效果往往不取决于算法选得多高级而取决于你喂给它的数据洗干净没有。在 Dataiku DSS 里承担这个“清洗加工”核心环节的就是 Prepare recipe准备步骤。很多人刚接触 DSS 时容易被可视化建模、自动机器学习这些炫酷功能吸引反而忽略了 Prepare recipe 这个最基础也最关键的模块。今天我就结合自己的实际项目经验把 Prepare recipe 从界面逻辑到核心操作、再到性能调优和踩坑实录一次讲透。先说结论Prepare recipe 是 DSS 里处理结构化数据尤其是表格型数据的“数据加工车间”。你不需要写一行代码就能完成列拆分、类型转换、空值处理、字符串清洗、行过滤、聚合前的预加工等绝大多数数据准备工作。而且它最大的优势在于每一步操作都会被自动记录成可视化的“步骤列表”可回溯、可复用、可维护完全告别了传统脚本里那种“改一处就要从头跑一遍”的窘境。1. 理解 Prepare recipe 的设计逻辑它凭什么能替代手工写清洗脚本1.1 核心需求解析为什么数据准备阶段决定了项目的成败我见过不少团队数据从各种业务系统导出后直接一股脑灌进模型训练。结果呢特征分布异常、空值率奇高、字段格式五花八门模型指标惨不忍睹最后还得回头排查数据问题耗时耗力。这里的关键在于数据准备不是“锦上添花”而是“地基工程”。Prepare recipe 设计出来就是为了把这部分脏活累活标准化、透明化。在 Dataiku DSS 中一个完整的数据管线通常是这样Source数据源→ Prepare recipe清洗加工→ Visual Recipe如 Group、Join、Pivot→ 模型训练或 Dashboard 展示。Prepare recipe 处于承上启下的位置它的输入是原始数据输出是干净、规整、可供下游分析或建模直接使用的数据集。1.2 方案选型背后的思考可视化步骤流 vs 传统 Python 脚本很多从 Pandas 转过来的朋友会问我在 Jupyter 里写df.dropna()、df[date] pd.to_datetime(df[date])不也一样吗为什么要用 Prepare recipe我自己对比过两者的差异。传统脚本的问题是第一可读性差一个月后回来看代码完全想不起来当时为什么这么写第二协作成本高团队成员改了一版脚本别人不知道改了哪里第三调试困难运行到一半报错只能靠 print 一点点排查。而 Prepare recipe 把每一步操作都可视化地列在左侧步骤栏中每一步做了什么、参数是什么、影响范围多大一目了然。注意Prepare recipe 并不是要完全替代代码。恰恰相反DSS 允许你在步骤中插入“Python 代码”步骤Code step处理那些可视化组件搞不定的复杂逻辑。它的正确使用姿势是80% 的常规清洗用可视化步骤搞定20% 的复杂变换用代码步骤补充。1.3 适用场景与边界什么时候该用 Prepare recipe什么时候不适合Prepare recipe 最适合以下场景单表或多表拼接后的字段清洗、格式统一。特征工程里的基础变换比如日期拆成年月日、文本统一大小写。数据质量检查比如快速定位异常值、空值分布。为下游 Group 或 Join 做预聚合准备。但如果你的数据是非结构化文本比如长文档、图像、或者需要大规模分布式计算比如百亿级记录Prepare recipe 就不是最优解了。这时你需要考虑 DSS 的 Notebook 或者 Spark 引擎来处理。总之工具选型要看场景别拿高射炮打蚊子也别拿小刀砍大树。2. 准备环境与数据我建议你从这三个地方开始2.1 环境准备Dataiku DSS 版本与安装要点我使用的是 Dataiku DSS 11.x 版本界面和 10.x 相比有一些细节调整但核心逻辑没变。如果你是自己搭建的 DSS 实例安装时有一点需要注意如果规划了 Prepare recipe 里的“采样/采样策略”功能建议安装时勾选 DSS 内置的 Python 环境并确保有足够的磁盘空间来存放中间缓存数据。我没有在安装环节浪费太多篇幅因为 DSS 的安装向导已经做得足够傻瓜化。不过有件事值得提醒如果你所在团队有多人协作建议把 DSS 的项目库Project Library纳入 Git 管理。这样别人改过的 Prepare recipe 步骤你能通过版本历史清晰地看到变化。这个习惯在很多项目里救过我。2.2 数据接入先从最简单的 CSV / Excel 开始初次上手 Prepare recipe 时建议先拿一份带点“脏数据”的 CSV 或 Excel 来练手。比如包含混合类型列、日期格式不统一、有缺失值、有重复行的数据。我自己常用的是某电商平台的订单导出一类数据字段大概有订单号、用户ID、下单时间、支付时间、商品类目、商品单价、购买数量、用户省份、是否会员等等。将数据导入 DSS 的 Flow 中后点击右上角的“Prepare”按钮DSS 就会创建一个 Prepare recipe并自动打开准备步骤编辑界面。这个界面你第一眼可能觉得信息量有点大但其实核心区域就几个中间是数据预览区展示当前步骤处理后的实时结果。左侧是步骤列表Steps按顺序记录你做的每一个操作。右侧是参数配置面板点击某个步骤时这里会显示对应的参数选项。底部有“采样”设置决定预览时是看全量数据还是抽样数据。2.3 数据预览策略采样模式不是越小越好关于采样设置我想多说一句。很多人为了图快把采样行数设置成 1 万行就完事了。但 Prepare recipe 里的某些操作比如计算分位数、识别离群值、字符串模糊匹配非常依赖全量统计信息。如果你只采样了 1 万行而实际数据有 1 亿行那么你在预览时看到的分布结果可能极具误导性下游模型也会跟着遭殃。我的习惯是初期排查数据结构用 10 万行采样做需要全量统计的操作如分位数、去重计数时切换到“无采样”或至少 50% 采样。虽然预览速度会慢一些但这笔时间花得值。3. 核心操作拆解Prepare recipe 的五类必备“手艺”3.1 列操作格式化、拆分、合并是日常主力Prepare recipe 的列操作里最常用的是 Format格式化、Split拆分、Concatenate合并这几个。我举两个实际例子。第一个例子日期格式统一。你从不同业务系统导出的下单时间有的长这样2024/1/5 10:30有的长这样202401051030还有的居然是 Excel 序列号比如45231.45。用 Format 列操作选择目标格式为yyyy-MM-dd HH:mm:ssDSS 会自动识别常见日期格式并完成转换。是不是比你在 Pandas 里来回pd.to_datetime()省心第二个例子信息拆分。比如“收货地址”这一列包含了“省-市-区-详细地址”四段信息你可以用 Split 操作按分隔符-拆成 4 列。操作时只需要选择要拆分的列、指定分隔符和目标列数即可DSS 会实时预览拆分结果。之后你会得到省、市、区、详细地址四个干净字段这在后续做地域维度的分析时简直不要太爽。提示拆分操作里有一个“保留原始列”的开关我建议勾选。不是因为原始列必须留在最终数据集而是因为数据清洗过程本身应该是可追溯的原始列可以作为校验依据。等你确认拆分结果完全正确后再决定是否删掉它。3.2 行操作过滤、去重、Top N 选择的高级用法行操作听起来简单但用好了能帮你解决很多隐蔽问题。先说过滤Filter。DSS 的过滤功能支持条件组合比如金额 100 且 状态 ! 已取消、省份 in (广东, 浙江)、下单时间是今天等等。这些条件的组合逻辑在右侧参数面板里一目了然比手写 SQL 的维护成本低多了。再说去重Deduplicate。这里要特别提醒去重前一定要想清楚“哪些列组合起来算重复”。如果你的订单表里有“用户ID 下单时间 商品ID”三个字段这三个字段完全相同的记录才算重复那去重时就要把这几个字段拖入分组条件中。很多新手直接对整个数据集去重结果把所有合法数据都搞没了这个坑我踩过不止一次。顺带提一下 Top N 选择。这个操作比较适合做“每个用户最近 3 笔订单”这类需求在 Prepare recipe 中实现非常直观先按用户ID分组再按订单时间排序最后选择 Top 3。对应的 SQL 写法虽然不难但 DSS 的可视化操作明显更利于你理解每一步在做什么。3.3 单元格操作空值、替换、清除的细节把握单元格级别的操作我单独拎出来说因为很多人在这一步处理得不够细致。最常用的是“空值处理”。你要先明确一个问题空值是该删除行、填充固定值、填充均值/中位数、还是用前后值填充这完全取决于业务含义。比如“支付时间”为空可能代表订单未支付你可以保留空值并在下游单独处理也可以填充为“未支付”比如“商品单价”为空如果只是个别行用同一类目下的中位数填充可能就是合理方案。DSS 在空值处理上提供了丰富选项你可以按列设置填充策略也可以对特定条件的行填充特定值。而且这些操作全部可视化下游同事一眼就能看懂你对空值做了什么。替换和清除也属于单元格级别的操作。比如把“男/女”统一成“M/F”把文本里的全角空格替换成半角把“暂无”这类特殊标记替换为空值等等。这些小细节看着不起眼但在数据建模时影响很大。比如你用字符串距离做特征匹配时一个不可见的全角空格就可能让“北京”和“北京”看起来完全不同。3.4 数据集信息操作Schema 调整、列重命名、类型转换Prepare recipe 在数据处理中还有一个容易被低估的作用调整 Schema表结构。比如你在读入数据时DSS 自动把“订单号”识别成了数值型但订单号中间有前导零比如001234。这时如果直接建模前导零会被丢掉。你就需要在 Prepare recipe 里新增一个“类型转换”步骤把订单号从数值型改成字符串型并且设置保留前导零。DSS 在处理这类“隐形数据损坏”时比代码方式更稳妥的地方在于每一步转换都有清晰的预览你能立刻发现转换前后是否发生了数据丢失。列重命名通常发生在字段名有歧义的时候。比如两个数据源合并后都有“金额”字段一个表示实际支付金额一个表示订单总额。我会先把下游需要重命名的列明确规定改名为pay_amount和order_amount。这样一来后续的 Group、Join、可视化报表都不容易搞混。3.5 引擎设置了解 DSS 到底用什么跑你的步骤Prepare recipe 有一个不太被注意但极其重要的选项引擎Engine选择。DSS 支持用不同的引擎执行 Prepare 步骤常见的有Python 引擎适合中小数据量依赖 Pandas灵活度最高能插入自定义 Python 代码。Spark 引擎适合大规模分布式数据能横向扩容。SQL 引擎部分场景如果数据源本身是数据库表DSS 可以把部分 Prepare 步骤翻译成 SQL 下推给数据库执行减少数据搬运。什么时候切换引擎我个人的经验是数据量在千万级以下用 Python 引擎顺手数据量上亿或者预览时明显卡顿就要切 Spark。另外如果你的下游步骤本身是 SQL 类的 Visual Recipe比如 Join、Group那把 Prepare 步骤尽量翻译成 SQL 下推可以减少从数据库到 DSS 引擎的数据传输负担整体管线性能会好很多。注意不是所有的 Prepare 步骤都能被 SQL 引擎完全翻译。像正则表达式提取、Python 代码步骤这类复杂逻辑SQL 引擎是搞不定的。DSS 会告诉你哪些步骤可以被下推哪些不能。这时你需要权衡是牺牲性能保持通用性还是适当调整实现方式让更多步骤能下推到 SQL。4. 实战案例从“脏乱差”订单表到可直接建模的数据集4.1 案例背景与数据概览为了让你直观感受 Prepare recipe 的完整流程我把之前做过的“电商订单数据清洗”案例拆解一遍。数据概况如下约 300 万行订单号字符串部分记录前导零被 Excel 吃掉。用户ID字符串包含个别重复值。下单时间混合格式有2024/1/5、2024-01-05 10:30:00、Excel 序列号三种。商品类目字符串大小写混杂比如“数码产品”“数码产品”。商品单价数值型存在空值也有个别负值异常数据。购买数量整数型正常范围 1~10有个别 999 的异常值。收货省份字符串存在“广东省”和“广东”两种表达。是否会员字符串“是/否”存在空值。目标产出统一日期格式为标准yyyy-MM-dd HH:mm:ss。订单号保留字符串格式且保留前导零。商品类目统一成小写并去除首尾空格。商品单价空值按类目中位数填充负值改为空值业务上单价不可能为负。购买数量中大于 100 的值都视为异常先置为空再按用户的平均购买数量填充。省份统一为“广东”这样的标准简称。是否会员空值统一填充为“否”。4.2 逐步操作全记录每个步骤的配置与背后逻辑第 1 步类型转换修复订单号右键点击“订单号”列选择“类型转换”把类型改为“字符串”并勾选“保留前导零”。预览区域立刻能看到原来的1234变成001234。这一步之所以放在最前面是因为后续去重、筛选时订单号的匹配必须基于完整的字符串形式。第 2 步格式统一清洗所有时间字段对“下单时间”列执行“格式化”操作目标格式选择yyyy-MM-dd HH:mm:ss。DSS 会自动识别三种不同格式的日期统一输出为标准格式。如果遇到无法识别的日期值DSS 会高亮显示并提示你手动处理或置空。这里我选择了“置空”因为在清洗阶段宁可让它空着也不能让脏格式混入下游。第 3 步字符串清洗处理类目和省份对“商品类目”列执行“小写化”操作然后执行“清除空格”去除首尾空格。对“收货省份”列执行“替换”操作把省字去掉同时把 “广西壮族自治区” 这类特殊表达统一成标准简称总之就是保证所有省份都是两个字的短名称。这个环节我用了“映射替换”的功能通过一个规则表把不同写法映射到标准名称比手动一行行改高效太多。第 4 步空值处理精细化填充策略这里我没有一刀切而是按列分别处理“商品单价”的空值先用 Group 方式计算每个类目的单价中位数然后执行“填充缺失值”选择“按分组填充”分组列为“商品类目”填充值为该组中位数。“是否会员”的空值直接填充为“否”逻辑是未记录会员身份的默认按非会员处理。第 5 步异常值处理把不可能的值清洗掉对“商品单价”添加筛选条件单价 0的行用“设置值为空”操作将负值置空然后再执行一次“空值填充”仍然按类目中位数填充。对“购买数量”添加 Filter数量 100视为异常将这些行的数量置空。接着用“按用户ID分组填充中位数”恢复合理值。这里要特别说明一个细节我在处理异常值时是先“置空”再“填充”而不是直接在原值上替换为统计值。这样做的原因是置空操作给数据流留下了一个明确的“检测痕迹”——之后即使统计口径变了你也能在步骤列表里清楚地看到哪些值被判定为异常、在哪个阶段被处理了。如果直接在原值上替换这个信息就丢失了。第 6 步去重精确定义重复逻辑右键选择“去重”把订单号作为唯一判断字段。这里我特意选了“保留第一条记录”的模式因为订单号重复在原始数据里大概率是同一订单被重复导入了两遍保留任意一条都可以。如果你希望保留最新的那一条可以通过排序步骤把最新记录排到最上面然后选择“保留第一条”。至此这个 6 步流程完成。左侧步骤列表会呈现类似这样的状态步骤序号操作类型目标列核心参数1类型转换订单号字符串保留前导零2格式化下单时间统一为 yyyy-MM-dd HH:mm:ss3小写化清除空格商品类目字符串小写去除首尾空格4替换收货省份省名映射规范5填充缺失值商品单价按类目中位数填充6筛选置空填充购买数量过滤异常值并按用户中位数填充7填充缺失值是否会员默认填充“否”8去重订单号保留第一条这个表格我建议你在实际项目中就用 DSS 自带的步骤注释功能给每个步骤加一段说明文字来记录比单独维护一份文档更不容易丢。4.3 跑完全流程后的数据质量评估所有步骤执行完后我习惯在 Prepare recipe 的输出面板里做三件事一是查看“列统计信息”确认没有极高的空值率残留。比如商品单价即使是按中位数填充后空值率应为 0。二是对关键列执行“异常值检测”或“分布检查”确保没有超出业务常识的值。比如购买数量不应再有 999 这样的离群点商品单价也不应出现负值。三是用“图表”快速可视化——在 Prepare 界面的右侧可以快速生成一个柱状图看类目分布确认清洗后的数据符合业务认知。比如数码产品的占比不会突然变得离谱。走到这一步数据基本可以放心交给下游的 Group 或建模流程了。5. 三处“内功心法”步骤管理、性能调优与代码扩展5.1 步骤管理为什么我建议你给每个步骤写注释Prepare recipe 的步骤列表支持拖拽重新排序。你可以在任意步骤后右键选择“插入步骤”或“复制步骤”。但最容易被忽略的是“给步骤加注释”。每次添加一个相对复杂的步骤时我都会右键点击步骤名选择“编辑注释”写清楚这个步骤在业务上的意图。比如“商品单价负值置空”这个步骤我会写单价不能为负业务规则见订单结算规范 v3.2此处先置空后续按类目中位数填充。一个月后你再回来看这个项目或者同事接手时都不需要靠猜来理解你的意图。这套“结构化日志”的能力传统 Pandas 脚本是比不了的。5.2 性能调优大数据的 Prepare recipe 到底该怎么提速很多人用 DSS 处理大数据时第一反应是抱怨“怎么这么卡”。我总结了几条实战调优思路。第一合理设置采样模式。如果你只是在做探索性清洗先跑一个小的采样集快速迭代步骤等逻辑确定后再切到全量运行输出最终结果。这在 DSS 里操作成本很低却能节省大量时间。第二把能下推的步骤尽量下推到数据库。如果数据源来自数据库表检查每一步是否被标记为“可下推”SQL。对于可下推的步骤DSS 会在执行时把它们翻译成 SQL 语句直接在源数据库执行返回结果集。这么做的收益很大——你有 300 万行数据如果每次都拉到 Python 引擎里跑网络传输和内存开销都很大如果能下推一部分过滤、聚合逻辑数据库帮你算好只回传结果速度完全不是一个量级。第三优先使用“分区/谓词下推”能力。如果你的数据源有分区字段比如按日期分区在 Prepare recipe 中先加一个过滤步骤把日期范围限定在最近几天后续所有步骤的数据量都会大幅减少。原理类似越早缩小数据量后续所有计算越轻松。第四检查是否有数据倾斜。如果你按某个高基数列做 Group 或 Join个别键值的数据量特别大比如“上海市”的订单占到 60%Spark 引擎计算时会发生严重的数据倾斜。如果你用的是 Spark 引擎可以在 DSS 的“高级设置”里调整分区数或者采用“加盐”策略重新分区。这个技巧比较高级但能处理一些极端的性能问题。5.3 代码扩展在合适的位置插入 Python 步骤虽然 Prepare recipe 的可视化步骤很强大但总有它覆盖不到的逻辑。比如你需要在文本列里提取特定模式的信息如从“订单备注加急-红色包装”中提取“加急”和“红色包装”虽然 DSS 也有“文本提取”功能但遇到特别复杂的规则时直接写一个 Python 步骤更省事。DSS 的 Python 代码步骤支持两种模式对整列应用自定义函数Apply on column。对整行应用自定义函数Apply on row。举个例子我曾在“商品标题”列里用正则表达式提取品牌信息写了一个 Python 函数应用到该列并输出为新列“品牌”。整个过程在 DSS 界面里嵌入依然能看到实时预览非常顺滑。注意在 Prepare recipe 中插入 Python 步骤会降低性能因为该类步骤无法被 SQL 下推也无法被 Spark 引擎优化到最优状态。所以在编写代码时尽量用向量化运算比如Series.str.extract避免逐行循环。5.4 与下游 Visual Recipe 的衔接Prepare 之后该做什么Prepare recipe 的输出通常直接进入下游的 Visual Recipe。你需要特别注意“输出 Schema 是否稳定”。如果下游用 Join 或 Group字段名和数据类型必须匹配。DSS 允许你在 Prepare recipe 的输出集中重命名字段、调整类型、删除无用字段。另外一个容易踩的坑是下游的图表或 Dashboard 会依赖字段名的稳定性。如果你改了 Prepare recipe 的步骤导致输出字段名变化Dashboard 上的图表可能直接失效。所以在调整 Prepare recipe 结构时我通常先看一下下游有哪些对象依赖这个输出集避免“牵一发而动全身”。6. 常见误区与问题排查实录6.1 误区一对空值“一刀切”填充很多新手面对空值习惯性选择“填充为 0”或“删除行”。这是我在实际项目中看到最普遍的问题。空值的处理逻辑必须结合业务含义。比如“用户年龄”为空你填充成 0那下游如果计算平均年龄直接就被拉低了如果填充成“未知”下游做分类模型时等于单独引入了一个类别。正确做法是先通过 DSS 的“列统计信息”查看空值占比再结合业务判断每个空值的业务含义最后选择填充策略。6.2 误区二没有固定“去重键”就盲目去重我在第 4 步案例里提到过去重这里再强调一次。去重前先问自己“什么条件算两个记录是重复的”如果只是订单号相同就算重复那没问题但如果你面对的是用户行为日志可能会遇到同一个人在同一秒内点击了两次同一个按钮这算不算重复如果只按用户ID去重那会把正常行为数据也删掉。DSS 的去重功能允许你选择任意多个字段作为分组条件务必谨慎选择。6.3 误区三忽略采样设置导致的误导性预览一个典型的翻车场景你在 1 万行采样里做类型转换当时看预览完全正常结果切到全量运行后发现某些列因为存在非常规值比如“金额”列里混入了几个“#N/A”类型转换直接报错或产生大量空值。解决思路就是我在 2.3 节说的涉及全量统计和类型推断时一定要扩大采样比例或直接全量预览。DSS 里可以一键切换“采样模式”这个按钮虽然小但请务必重视。6.4 常见报错速查表报错信息或异常现象常见原因解决思路类型转换预览正常但全量运行时报错全量数据中存在样本中未覆盖的脏数据先筛选出格式特殊的值手动修正后再转换“无法识别日期格式”日期字符串中含有空格、引号或混合时区先做清洗再去掉非法字符最后格式化“Compute failed: No suitable engine”当前步骤无法由所选引擎执行切换引擎或将该步骤改为 Python 代码步骤输出行数异常偏少过滤条件写错或去重字段组合过于激进逐条检查过滤条件预览时开启“行数变化”提示执行流程速度极慢采样模式设置过大、存在数据倾斜、不可下推步骤过多缩小采样、检查数据分布、尽量下推 SQL6.5 经验心得越早把数据问题暴露出来越好我在实际项目里还有个习惯在 Prepare recipe 里故意添加几个“数据质量检查步骤”。比如对“金额”列加一个计算空值率、对“日期”列加一个计算最小最大值的步骤这些不会修改数据但能让数据问题尽早暴露。DSS 的“检查点Checkpoint”功能很适合这个场景它允许你设置一些质量规则当数据不满足条件时直接让流程失败或告警。这比数据都已经建模完成后再发现异常成本低太多了。7. 最后的经验分享老实说Dataiku DSS 里值得深入研究的模块很多机器学习可视化建模、AutoML、MLOps 都很吸引眼球。但如果你问我一个数据项目里最值得打磨的地方我的答案永远是数据准备环节。Prepare recipe 就像厨房里的切配台——菜洗没洗净、切得均不均匀直接决定了大厨能炒出什么水平的菜。聊到这儿再分享一个小技巧当你第一次接触一个全新数据集的 Prepare recipe 时花十分钟把每一列的空值率、类型、唯一值数量看一遍。这十分钟的“慢”能帮你省下后面至少两个小时的“快”。你在使用 Prepare recipe 时遇到过什么奇怪的数据问题吗欢迎在评论区聊聊你踩过的坑——我们一起把数据准备这块硬骨头啃得更明白。