
数据分析数据工程机器学习【免费下载链接】cudfcuDF - GPU DataFrame Library项目地址https://gitcode.com/gh_mirrors/cu/cudf点击查看免费下载本篇技术文章围绕 libcudf 文档体系中的 “Column Reorder”列重排API 分组展开对应文档页 column_reorder.rst。该分组是 libcudf 中所有“按某种规则重新排列行顺序”能力的总入口下分两个子分组Partitioning行分区重排文档页 reorder_partition.rst和 Stream Compaction流式压缩/行过滤文档页 reorder_compact.rst。读完本文后你将掌握partition、hash_partition、round_robin_partition三种分区重排 API 的签名、参数语义与边界行为以及drop_nulls、drop_nans、apply_retention_mask、unique、distinct等流式压缩 API 的用法、废弃演进与源码/测试定位方式。1. Column Reorder 分组在 libcudf 中的定位column_reorder.rst 本身是一个 Doxygen 分组页面其内容只有一个指令.. doxygengroup:: column_reorder :members:以及指向两个子页面的 toctreereorder_partition、reorder_compact。分组的层级结构在 doxygen_groups.h 中定义defgroup column_reorder Reordering { defgroup reorder_partition Partitioning defgroup reorder_compact Stream Compaction }从源码结构看这两个addtogroup标记分别落在两个公开头文件中也就是说Column Reorder 分组的实际 API 集合 partitioning.hpp stream_compaction.hppcpp/include/cudf/partitioning.hpp 开头即为addtogroup reorder_partitioncpp/include/cudf/stream_compaction.hpp 开头即为addtogroup reorder_compact。这两个头文件共同构成了 GPU 上“重排行”的两类原语一类是把同一分组的行聚拢成连续块分区另一类是把不满足条件的行从序列中剔除压缩。二者输出都带有明确的“稳定”或“未定义序”语义这是使用时必须理解的关键点。2. Reorder Partition行分区重排Partitioning 子分组定义于 partitioning.hpp文件头注释写明其用途为 “Column partitioning APIs”。它提供 4 个公开函数和 1 个枚举。2.1 哈希函数选择hash_idenum class hash_id : int32_t { HASH_IDENTITY 0, /// 恒等哈希直接返回待哈希的 key HASH_MURMUR3 /// Murmur3 哈希函数 };定义见 partitioning.hpp#L32-L35。hash_partition的默认哈希函数为HASH_MURMUR3默认种子为头文件中定义的DEFAULT_HASH_SEED该常量来自 hashing.hpp通过#include cudf/hashing.hpp引入。2.2partition按显式分区映射重排签名见 partitioning.hpp#L71-L76std::pairstd::unique_ptrtable, std::vectorsize_type partition( table_view const t, column_view const partition_map, size_type num_partitions, cuda::stream_ref stream cudf::get_default_stream(), rmm::device_async_resource_ref mr cudf::get_current_device_resource_ref());语义要点均来自头文件 Doxygen 注释对t中第i行partition_map[i]指定该行属于哪个分区输出的新表中同一分区的行连续放置整体按分区号升序[0, num_partitions)排列分区内部的行序未定义。返回num_partitions 1个偏移量offsets分区i的行位于[offsets[i], offsets[i1])。若某个分区值j未出现在partition_map中则该分区为空即offsets[j1] - offsets[j] 0。约束与异常partition_map的值必须在[0, num_partitions)内否则行为未定义partition_map非整数类型 → 抛cudf::logic_errorpartition_map.has_nulls() true→ 抛cudf::logic_errorpartition_map.size() ! t.num_rows()→ 抛cudf::logic_error。这是一个“分区结果已知、只要求重排”的底层原语上层可以先用hash_partition或任何自定义逻辑算出partition_map再调用partition完成物理重排。2.3hash_partition按列哈希自动分区hash_partition有两个重载都返回std::pairstd::unique_ptrtable, std::vectorsize_type。重载一按列索引哈希partitioning.hpp#L103-L110std::pairstd::unique_ptrtable, std::vectorsize_type hash_partition( table_view const input, std::vectorsize_type const columns_to_hash, // 参与哈希的列下标 int num_partitions, hash_id hash_function hash_id::HASH_MURMUR3, uint32_t seed DEFAULT_HASH_SEED, cuda::stream_ref stream cudf::get_default_stream(), rmm::device_async_resource_ref mr cudf::get_current_device_resource_ref());重载二按 keys 表哈希partitioning.hpp#L138-L145std::pairstd::unique_ptrtable, std::vectorsize_type hash_partition( table_view const input, table_view const keys, // 指定参与哈希的键表 int num_partitions, hash_id hash_function hash_id::HASH_MURMUR3, uint32_t seed DEFAULT_HASH_SEED, ...);两个重载的行为约定一致行被分入num_partitions个桶同一桶的行在输出表中连续存放偏移向量长度为num_partitions 1最后一个偏移恒等于输出表总行数。空columns_to_hash或零列keys表被视为空输入即使input行数非零也返回空结果不抛错。重载一的异常columns_to_hash中下标非法时抛std::out_of_range重载二keys非空且行数与input不一致时抛std::invalid_argument。分区内行序同样未定义——这是分布式哈希连接、并行 groupby 等场景所需要的“桶均衡”性质而非有序性保证。2.4round_robin_partition轮询分区签名见 partitioning.hpp#L286-L291std::pairstd::unique_ptrcudf::table, std::vectorcudf::size_type round_robin_partition( table_view const input, cudf::size_type num_partitions, cudf::size_type start_partition 0, cuda::stream_ref stream cudf::get_default_stream(), rmm::device_async_resource_ref mr cudf::get_current_device_resource_ref());行按其在表中的行下标以轮询方式分配给各分区。头文件注释给出了一个形象的“发牌”类比partitioning.hpp#L160-L183一副牌 表的行玩家数 分区数start_partition 从哪个玩家开始发牌结果一把每位玩家的牌按顺序叠回一副新牌堆玩家 0 在前结果二一个偏移向量指示每位玩家的牌堆从哪个位置开始。异常约束num_partitions 1或start_partition num_partitions时抛cudf::logic_error。当num_partitions nrows时从起始玩家开始发牌直到牌发完没拿到牌的分区表现为offset[i] offset[i1]空分区。头文件中给出了 9 个完整示例partitioning.hpp#L185-L275这里摘录两个典型示例 1: 输入: table col 1 {0, ..., 12} (13 行) num_partitions 3, start_partition 0 输出: table col 1 {0,3,6,9,12, 1,4,7,10, 2,5,8,11} partition_offsets {0, 5, 9, 13} 示例 6: 输入: table col 1 {0, ..., 10} (11 行) num_partitions 15 num_rows 11, start_partition 2 输出: table col 1 {0,1,2,3,4,5,6,7,8,9,10} (行序不变) partition_offsets {0,0,0,1,2,3,4,5,6,7,8,9,10,11,11,11}示例 6 值得注意当分区数远大于行数时轮询退化为“每分区至多 1 行”空分区以连续相等偏移表示。2.5 Partitioning 的源码与测试位置从源码结构看分区重排的实现集中在 cpp/src/partitioning/ 目录partitioning.cu 承载partition/hash_partitionround_robin.cu 承载轮询分区。对应测试位于 cpp/tests/partitioning/包括partition_test.cpphash_partition_test.cppround_robin_test.cpp如果要验证某个分区行为例如空columns_to_hash的退化语义直接读对应测试文件即可复现头文件注释中的边界约定。3. Reorder Compact流式压缩行过滤Stream Compaction 子分组定义于 stream_compaction.hpp文件头注释写明 “Column APIs for filtering rows”。它提供两组能力按 null/NAN 条件过滤按布尔掩码过滤以及去重去重本质是“保留满足去重条件的行”。3.1 按 null 过滤drop_nulls带阈值版本stream_compaction.hpp#L73-L78std::unique_ptrtable drop_nulls( table_view const input, std::vectorsize_type const keys, // 参与判定的列下标 cudf::size_type keep_threshold, // 行内至少多少个非 null 字段才保留 cuda::stream_ref stream cudf::get_default_stream(), rmm::device_async_resource_ref mr cudf::get_current_device_resource_ref());头文件给出的伪代码示例stream_compaction.hpp#L49-L59input {col1: {1, 2, 3, null}, col2: {4, 5, null, null}, col3: {7, null, null, null}} keys {0, 1, 2} // 全部三列 keep_threshold 2 output {col1: {1, 2}, col2: {4, 5}, col3: {7, null}}即第 2、3 行在 keys 中非 null 字段数分别为 2 和 1只有满足 keep_threshold的行被保留。要点该操作是稳定的输入行序在输出中保持输入中不可空non-nullable的列被视为“全非 null”若input零行、或keys为空、或 keys 无 null不报错返回空表。无阈值版本stream_compaction.hpp#L107-L111等价于keep_threshold keys.size()即 keys 列必须全部非 null才保留该行。3.2 按 NAN 过滤drop_nans签名与drop_nulls完全平行但判定对象是浮点 NaN带阈值版stream_compaction.hpp#L151-L156与无阈值版stream_compaction.hpp#L186-L190。约束keys 列必须为浮点类型否则抛cudf::logic_error同样是稳定操作空输入/空 keys 返回空表。头文件示例阈值版stream_compaction.hpp#L125-L135input {col1: {1.0, 2.0, 3.0, NAN}, col2: {4.0, null, NAN, NAN}, col3: {7.0, NAN, NAN, NAN}} keys {0, 1, 2}, keep_threshold 2 output {col1: {1.0, 2.0}, col2: {4.0, null}, col3: {7.0, NAN}}注意 null 与 NaN 是相互独立的两种“缺失”drop_nans只按 NaN 计数null 字段不影响判定示例中 col2 第 2 行为 null 仍被保留。3.3 布尔掩码过滤apply_retention_mask/apply_deletion_mask保留掩码stream_compaction.hpp#L214-L218std::unique_ptrtable apply_retention_mask( table_view const input, column_view const retention_mask, // 必须为 type_id::BOOL8可空 cuda::stream_ref stream cudf::get_default_stream(), rmm::device_async_resource_ref mr cudf::get_current_device_resource_ref());掩码中非 null 且为true的行被复制到输出掩码为 null 或false的行被剔除。掩码为空或输入零行 → 返回空表非空输入与掩码行数不一致 → 抛cudf::logic_error掩码类型不是BOOL8→ 抛cudf::logic_error。删除掩码stream_compaction.hpp#L262-L266语义相反掩码中非 null 且为false的行被剔除掩码为空时返回输入的拷贝。演进提示旧 APIapply_boolean_maskstream_compaction.hpp#L233-L237已标注[[deprecated]]注释写明自 release 26.10 起弃用应改用apply_retention_mask。新代码应直接以“保留/删除”两个方向显式表达意图。3.4 去重unique/distinct/stable_distinct/distinct_indices去重语义由枚举duplicate_keep_optionstream_compaction.hpp#L271-L276控制enum class duplicate_keep_option { KEEP_ANY 0, /// 保留不指定的某一个重复行 KEEP_FIRST, /// 保留第一次出现 KEEP_LAST, /// 保留最后一次出现 KEEP_NONE /// 重复行全部删除 };四个 API 的分工API行序保证额外参数说明uniqueL309-L315保持输入顺序nulls_equal默认EQUAL去除相邻等价行稳定distinctL341-L348不保证顺序nulls_equalnans_equal默认ALL_EQUAL全局去重输出无序stable_distinctL403-L410保持输入顺序同distinct与distinct输出行集合相同但保留输入序distinct_indicesL368-L374—同distinct但作用于全表列返回去重行对应的行号列不拷贝数据值得注意的实现约定来自头文件注释unique与distinct都支持只按keys列判重其余列随行拷贝零列输入视为空返回空表性能提示若输入已预排序用unique可以得到与distinct相同的输出行集合但运行时间更短unique是相邻判重distinct需要全局哈希/排序stable_distinct对KEEP_ANY的语义有精确说明保留的是输入序中的“某个”重复行例如 keys 列1, 2, 1、values 列3, 4, 5结果可能是 values3, 4或4, 5但不会出现4, 3或5, 4stream_compaction.hpp#L385-L388。去重的测试用例分布在 cpp/tests/stream_compaction/ 目录含unique、distinct、stable_distinct、apply_mask等测试文件由 ci/discover_libcudf_tests.sh 发现的 CTest 目标覆盖。3.5 已弃用的 UDF/ASTfilter系列stream_compaction.hpp中还有三个filter重载基于 UDF 的列过滤L451-L459、带filter_input列/标量变体的扩展版L506-L514、以及基于 AST 表达式的表过滤L542-L546。三者均标注[[deprecated]]自 release 26.12 起官方推荐的替代路径是用cudf::transform或cudf::compute_column先算出布尔掩码列再调用apply_retention_mask或apply_deletion_mask完成过滤。这一“先掩码、后压缩”的两步式写法是当前推荐的流式压缩主路径也解释了为什么掩码 API 被拆成 retention/deletion 两个显式方向。4. 公共约定stream 与 mr 参数两个头文件中的所有 API 共享同一套尾部参数cuda::stream_ref stream cudf::get_default_stream()设备内存操作与 kernel 启动所用的 CUDA stream默认值定义见 default_stream.hpprmm::device_async_resource_ref mr cudf::get_current_device_resource_ref()结果设备内存使用的 RMM 资源默认取当前设备资源memory_resource.hpp。这意味着所有重排/压缩操作都可以无缝接入调用方的 stream 编排与自定义内存资源如池化分配器是构建多流管线如 IO → 分区 → 计算时的基本前提。返回类型也有统一模式分区类 API 返回std::pairunique_ptrtable, vectorsize_type表 偏移向量过滤类 API 直接返回unique_ptrtabledistinct_indices返回unique_ptrcolumn行号列。偏移向量的统一约定是长度num_partitions 1、末位等于输出总行数可用slice/gather等 API 按[offsets[i], offsets[i1])切出各分区。5. 小结与延伸阅读Column Reorder 分组是 libcudf 行级重排原语的集合分区侧提供partition显式映射、hash_partition列/键表哈希默认 Murmur3、round_robin_partition轮询发牌三个重排工具压缩侧提供drop_nulls/drop_nans阈值化 null/NAN 过滤、apply_retention_mask/apply_deletion_mask布尔掩码过滤、unique/distinct/stable_distinct/distinct_indices去重四组过滤工具。所有 API 均遵循stream/mr双参数约定并在头文件注释中以伪代码示例明确了空输入、空分区等边界语义。继续深入可参考的路径文档页column_reorder.rst、reorder_partition.rst、reorder_compact.rstAPI 头文件partitioning.hpp、stream_compaction.hpp实现cpp/src/partitioning/、cpp/src/stream_compaction/测试cpp/tests/partitioning/、cpp/tests/stream_compaction/。赞分享数据分析数据工程机器学习【免费下载链接】cudfcuDF - GPU DataFrame Library项目地址https://gitcode.com/gh_mirrors/cu/cudf点击查看免费下载相关推荐深入cuDF核心架构从libcudf到Python API深入cuDF核心架构从libcudf到Python API 本文深入解析了cuDF的核心架构体系从底层的libcudf C计算引擎到Python绑定层p数据分析数据工程机器学习cuDF Stream Compaction 指南基于 reorder_compact Doxygen 组的行筛选与去重 API 全解析cuDF Stream Compaction 指南基于 reorder_compact Doxygen 组的行筛选与去重 API 全解析 本篇技术指南围绕 c数据分析数据工程机器学习让 2007 款的 Mac 重新跑起最新 macOSOpenCore Legacy Patcher 完整操作教程让 2007 款的 Mac 重新跑起最新 macOSOpenCore Legacy Patcher 完整操作教程 你点进「系统更新」发现更新按钮是灰的——这数据分析数据工程机器学习上一篇Memcached Session Manager终极Tomcat会话管理解决方案完全指南下一篇uWebSockets.js分布式缓存集成提升数据访问速度创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考