【问题标题】:R fuzzy join with big dataframesR模糊连接与大数据框
【发布时间】:2021-11-11 14:40:46
【问题描述】:

我想做一个基于模糊匹配的left_join(df1, df2)。 我的df1 有 100k 行大,我的df2 有 25k 行大。 基本上我想用 jaro winkler 方法计算字符串相似度 在两个数据帧的join_colum 之间。所以这将是 100k * 25k 的比较。

我只想匹配一个而不是多个。所以我的目标是 取字符串相似度最高的匹配项。除此之外,我会 仅当 jaro winkler 字符串相似度至少为 0.8 时才喜欢加入(假设在我编写的示例中满足此条件)。

我试图展示输入的样子以及我希望输出的内容, 但是,由于我的数据框的大小,我正在努力实现实际实现。 我已经尝试过功能 来自fuzzyjoin库,但我遇到了内存问题。 我也尝试使用 strindist 包中的 amatch 函数,但我无法 让它工作。

我无法调整这两种解决方案来解决我的问题: fuzzy LEFT join with R, fuzzy outer join/merge in R

library(tidyverse)

df1 <- data.frame(
  id = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  join_column = c("alice123burgerstorechicago", "alicewonderland",
                  "bubbletea45london", "blueonion",
                  "chandle34song", "crazyjoeohio",
                  "donaldduckshop123", "dartcommunitygermany",
                  "evergreen78hall", "exittheroom15florida"))


df2 <- data.frame(
  id = c(15, 16, 18, 20),
  join_column = c("aliceburgerstorechicag", 
                  "bubbletealndon",
                  "crazyjoeohio178",
                  "exittheroom25florid"))


pre_target <- df1
target <- pre_target %>% 
  mutate(joined_with_id = c(15, NA, 16, NA, NA, 18, NA, NA, NA, 20),
         joined_with_string = c("aliceburgerstorechicag", NA, 
                                "bubbletealndon", NA, NA, 
                                "crazyjoeohio178", NA, NA, NA, 
                                "exittheroom25florid"))

【问题讨论】:

    标签: r stringdist fuzzyjoin


    【解决方案1】:

    无论您如何处理,比较的数量都是巨大的,而且总是很慢。没有什么可以防止这种情况的模糊连接。需要进行模糊匹配,而加入是容易的部分,因为您不要尝试加入模糊部分,而是根据匹配找到的匹配。

    这里有一个关于您的小样本集的演示,它至少显示了连接是如何完成的。

    library(data.table)
    library(stringdist)
    
    setDT(df1)
    setDT(df2)
    
    df1_options_to_join <- df1$join_column
    
    my_best_match_function <- function(x) {
      z <- stringdist(x, df1_options_to_join, method = "jw")
      z <- setNames(df1_options_to_join, z)
      if(as.numeric(min(names(z))) <= 0.20) { # equals your 0.80 similarity
        return(z[min(names(z))])
      } else {
        return(NA)
      }
    }
    
    df2[, match_to_join := my_best_match_function(join_column), by = join_column]
    
    target <- merge(df1, df2, by.x = "join_column", by.y = "match_to_join", all = T)
    

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 2020-03-02
      • 2020-04-02
      • 1970-01-01
      • 2018-05-22
      • 2017-01-31
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      相关资源
      最近更新 更多