You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用tidyr高效实现分组内品类全组合匹配(大数据场景)

高效实现:按公司关联Shirts与Pants的所有商品组合

数据背景

现有一个包含company、product_type和product_ID三列的DataFrame,其中product_ID为全局唯一的商品ID。示例数据构造代码及输出如下:

input_example <- data.frame(company = c(rep("companyA", 4), rep("companyB", 6)), 
                            product_type = c(rep("shirts", 3), "pants", rep("shirts",4), rep("pants", 2)), 
                            product_ID = seq(1,10))

输出结果:

> input_example
    company product_type product_ID
1  companyA       shirts          1
2  companyA       shirts          2
3  companyA       shirts          3
4  companyA        pants          4
5  companyB       shirts          5
6  companyB       shirts          6
7  companyB       shirts          7
8  companyB       shirts          8
9  companyB        pants          9
10 companyB        pants         10

需求说明

获取每个company下shirts与pants的所有唯一组合,并关联对应的product_ID,期望输出如下:

> output
    company product_type.x product_ID.x product_type.y product_ID.y
1  companyA         shirts            1          pants            4
2  companyA         shirts            2          pants            4
3  companyA         shirts            3          pants            4
4  companyB         shirts            5          pants            9
5  companyB         shirts            5          pants           10
6  companyB         shirts            6          pants            9
7  companyB         shirts            6          pants           10
8  companyB         shirts            7          pants            9
9  companyB         shirts            7          pants           10
10 companyB         shirts            8          pants            9
11 companyB         shirts            8          pants           10

当前方案问题

目前采用split结合inner_join的实现方式,在1亿行级别的业务数据下运行速度极慢,即使使用并行lapply也无明显改善:

output <- split(input_case, input_case$company) %>% lapply(., function(x){
  
  x %>% inner_join(x, by=c("company")) %>% filter(product_type.x != product_type.y)
  
}) %>% do.call(rbind,.) %>% filter(product_ID.x < product_ID.y) %>% remove_rownames()

基于tidyr/dplyr的高效实现方案

通过先筛选目标类型子集,再按公司做内连接的方式,避免全表自连接带来的冗余计算,大幅提升处理效率:

library(dplyr)
library(tidyr)

# 1. 分别筛选出shirts和pants的数据集,并重命名列名
shirts_data <- input_example %>%
  filter(product_type == "shirts") %>%
  rename(product_type.x = product_type, product_ID.x = product_ID)

pants_data <- input_example %>%
  filter(product_type == "pants") %>%
  rename(product_type.y = product_type, product_ID.y = product_ID)

# 2. 按company做内连接,直接得到所有shirts与pants的组合
output <- shirts_data %>%
  inner_join(pants_data, by = "company")

方案优势

  • 减少冗余计算:仅处理需要的两类商品数据,避免了全表自连接产生的同类型商品无效组合,大幅降低中间数据量
  • 向量化操作:基于dplyr的向量化处理逻辑,比循环/split的方式更适配大数据量场景
  • 逻辑清晰:直接明确筛选目标类型后连接,代码可读性高,易于维护

如果业务数据中存在shirts的product_ID大于pants的情况,可在最后添加filter(product_ID.x < product_ID.y)来匹配需求中的ID顺序要求。

内容的提问来源于stack exchange,提问作者irene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:20:45