ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Daft 类型转换完全指南:Casting Matrix、cast 函数与底层 Rust 实现

Daft 类型转换完全指南:Casting Matrix、cast 函数与底层 Rust 实现 Daft 类型转换完全指南Casting Matrix、cast 函数与底层 Rust 实现【免费下载链接】DaftHigh-performance data engine for AI and multimodal workloads. Process images, audio, video, and structured data at any scale项目地址: https://gitcode.com/GitHub_Trending/da/DaftDaft 中的cast是连接 DataFrame 列、UDF 返回值与多模态数据类型之间的关键机制。本文基于仓库文档 docs/api/datatypes/casting.md完整讲解 Daft DataType 之间的兼容转换矩阵、cast函数的三种目标类型写法以及 UDFreturn_dtype、Series.from_pylist等隐式转换场景并结合 Rust 源码说明转换在底层是如何执行的、溢出时为何发生回绕。一、什么是 Casting MatrixCasting Matrix类型转换矩阵是对 Daft 各数据类型DataType之间谁可以被转换到谁的高层概览。它是回答以下问题的权威依据某列能否直接cast到目标类型还是必须先转成中间类型如经Utf8中转多模态类型Image、Tensor、Embedding 等之间哪些转换是合法的UDF 声明return_dtype后Daft 会自动把返回值转换到哪个类型。转换入口主要有两个 API表达式层面cast函数即daft.functions.cast或直接使用Expression.cast列层面Series.cast。此外某些操作会隐式触发转换例如UDF 结果匹配声明的return_dtype或带dtype参数调用Series.from_pylist时详见 docs/api/datatypes/casting.md 原文说明。二、cast 的三种目标类型写法cast函数签名为cast(expr, dtype)其实现位于 daft/functions/misc.pyimport daft from daft.functions import cast df daft.from_pydict({float: [1.0, 2.5, None]}) df df.select(df[float].cast(daft.DataType.int64()))dtype参数DataTypeLike支持三种写法源码中通过DataType._infer(dtype)统一归一化见 daft/datatype.py 中_infer方法写法示例归一化路径Daft DataType 对象daft.DataType.int64()直接返回Python 内置类型str/int/floatinfer_from_typeint→ Int64、str→ Utf8SQL 类型字符串string/int/tinyint交给 SQL 引擎解析from_sql官方文档字符串中的完整示例展示了这些写法并存的效果df daft.from_pydict({a: [1, 2, 3]}) df df.select( df[a].cast(str).alias(str), # String df[a].cast(int).alias(int), # Int64 df[a].cast(float).alias(float), # Float64 df[a].cast(string).alias(sql_string), # String df[a].cast(int).alias(sql_int), # Int32 df[a].cast(tinyint).alias(sql_tinyint) # Int8 )注意 SQL 字符串写法解析出的类型与 Python 类型写法并不完全相同int解析为 Int32 而非 Int64这在构造 schema 时值得留意。三、完整 Casting Matrix 可以转换 不可以转换。行是源类型FROM列是目标类型TOFROM ↓ \ TO →NullBooleanInt8Int16Int32Int64UInt8UInt16UInt32UInt64Float32Float64Decimal128TimestampDateTimeDurationIntervalBinaryFixedSizeBinaryUtf8ListFixedSizeListStructMapEmbeddingImageFixedShapeImageTensorFixedShapeTensorSparseTensorFixedShapeSparseTensorPythonFileNullBooleanInt8Int16Int32Int64UInt8UInt16UInt32UInt64Float32Float64Decimal128TimestampDateTimeDurationIntervalBinaryFixedSizeBinaryUtf8ListFixedSizeListStructMapEmbeddingImageFixedShapeImageTensorFixedShapeTensorSparseTensorFixedShapeSparseTensorPythonFile注意原文档强调溢出值会回绕wrap。例如256转换为无符号 8 位整数UInt8后得到0。做数值收窄转换时务必自行检查值域。矩阵中值得记住的规律Null 是万能源类型Null 列可以转换成任何类型本质是生成全 null 的目标类型数组反向看几乎所有类型也都能转回 Null但 Interval 与 File 不行。Python 是万能双向类型Python 对象列可转换为任何类型任何类型也可转换为 Python 列——这依赖逐元素取值再包装为 Python 对象代价较高适合调试而非生产链路。File 类型几乎是孤岛只有 Null 和 Python 能转换成 FileFile 自身不能转换成其他任何类型文件处理通常走专用函数而非 cast。数值/时间家族高度互通整数、浮点、布尔、时间日期类型之间基本两两可转Interval、Duration 等少量例外Decimal128 不能与 Boolean 互转、不能直接转 Utf8。复杂类型走同构族List、FixedSizeList、Struct、Map、Embedding 之间仅在形状兼容时互转如 List ↔ FixedSizeList ↔ EmbeddingStruct ↔ Embedding且几乎都能从 Utf8 转成 List用于解析 JSON 字符串反之 Struct/FixedShapeTensor 等可转回 Utf8。多模态类型只认亲戚Image ↔ FixedShapeImage ↔ Tensor ↔ FixedShapeTensor ↔ SparseTensor 系列内部按固定形状/变长形状对齐互转均可经 Python 中转它们不能直接转成数值或字符串。四、溢出回绕与 Binary 转换路径Rust 实现视角Python 侧的cast最终落到 Rust 的Series::cast核心实现在 src/daft-core/src/array/ops/cast.rs。从源码结构看有几个关键行为与矩阵文档一一对应1. Null 分支。源类型或目标类型为 Null 时直接返回全 null 数组这解释了矩阵中 Null 行的全绿// src/daft-core/src/array/ops/cast.rs if self.data_type().is_null() || dtype.is_null() { return Ok(Series::full_null(self.name(), dtype, self.len())); }2. 数值转换委托给 Arrow溢出即回绕。DataArray覆盖 Int8–Int64、UInt8–UInt64、Float 等 Arrow 数值类型的cast直接复用 arrow-rs 的 casting 机制Arrow 的整型 cast 采用 wrapping回绕语义这正是文档中256 cast 到 UInt8 得 0的实现来源。3. 数值/布尔 ↔ Binary 走字符串语义。源码注释明确指出arrow-rs 的整数到 Binary 会直接拷贝原始字节1i32 - b\x01\x00\x00\x00而 Daft 保持了 arrow2 时代的字符串表示语义1i32 - b1因此所有 numeric/bool → Binary 的转换都被路由经过 Utf8 中转bool → Binary 则先转 UInt8 再经 Utf8得到b1/b0而非btrue/bfalse// src/daft-core/src/array/ops/cast.rs节选 if src.is_boolean() is_binary_target { let int_series self.cast(DataType::UInt8)?; let utf8_series int_series.cast(DataType::Utf8)?; return utf8_series.cast(dtype); } if src.is_numeric() is_binary_target { let utf8_series self.cast(DataType::Utf8)?; return utf8_series.cast(dtype); }这一点在使用矩阵时很重要文档标注的是能否转换而实际字节内容遵循十进制字符串约定。4. Python 类型转换。转 Python 时逐元素取 Literal 再包装为 Python 对象cast_to_python转 Extension 类型时会先 cast 到其底层 storage 类型再包上扩展元数据。时间类型还内置了cast_to_seconds/milliseconds/...等 time unit 换算路径支撑 Timestamp/Duration 家族之间的换算。五、隐式转换的两个典型场景除显式调用cast外矩阵同样约束以下隐式场景原文档明确列出的两类1. UDF 的 return_dtype声明了return_dtype的 UDFDaft 会把返回值隐式 cast 到该类型。返回类型的推断逻辑见 daft/udf/udf_v2.pyreturn_dtype参数优先其次使用函数返回类型注解DataType._infer支持 SQL 字符串与 Python 类型两种写法。若声明的return_dtype与真实返回类型不在矩阵的绿色区域运行时会报类型错误——因此声明return_dtype前应先查一遍 Casting Matrix。2. Series.from_pylist 的 dtype 参数调用Series.from_pylist(data, name, dtype)时若指定了dtypePython 列表中的元素会被转换到目标类型例如把int列表强制为DataType.int8()。daft/series.py 中Series.cast与Series.try_cast是这一层的直接入口s daft.Series.from_pylist([1, 2, 3], namex, dtypedaft.DataType.int32()) s2 daft.Series.from_pylist([1, 2, bad], namey) s2.cast(daft.DataType.int32()) # 失败即抛错 s2.try_cast(daft.DataType.int32()) # 失败返回 null3. 补充try_cast —— 宽松版 cast矩阵描述的是能不能转而当源数据不干净如 Utf8 列中混有非法数字时应改用try_cast可转换的值正常转换失败的值置为 null 而不是让整个 query 失败实现同样经由 daft/series.py 的try_cast与 daft/functions/misc.py 的try_cast函数。六、实战建议清单收窄数值前先确认值域矩阵允许 Int64 → UInt8 等转换但溢出会回绕而非报错无法确认值域时改用try_cast并检查 null 比例。解析 JSON/数组字符串Utf8 → List 是绿色路径是字符串列变数组列的标准做法反过来把 Struct/Embedding 转回字符串则依赖对应列的字符串表示。多模态列落地前对齐形状变长 Image 转 FixedShapeImage、变长 Tensor 转 FixedShapeTensor 只在矩阵允许的方向上进行跨形状家族如 SparseTensor → Tensor需确认绿格必要时经 Python 中转注意性能代价。UDF 声明与数据流类型闭环return_dtype声明、from_pylist(dtype...)输入都会触发隐式 cast把 Casting Matrix 当作 schema 契约检查表能在写入 Parquet / 下游算子前拦截不兼容的类型组合。七、延伸阅读仓库内相关位置转换矩阵原文与交互说明docs/api/datatypes/casting.mdcast/try_cast函数定义与示例daft/functions/misc.pyExpression.castdaft/expressions/expressions.pySeries.cast/Series.try_cast/from_pylistdaft/series.pyDataType._inferSQL 字符串 / Python 类型归一化daft/datatype.pyUDF 返回类型推断_get_return_dtypedaft/udf/udf_v2.pyRust 转换核心实现含 Null 分支、Binary 路由、Python 转换src/daft-core/src/array/ops/cast.rs【免费下载链接】DaftHigh-performance data engine for AI and multimodal workloads. Process images, audio, video, and structured data at any scale项目地址: https://gitcode.com/GitHub_Trending/da/Daft创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表