【问题标题】:SparkR: levenshtein Fuzzy string matching between 2 variables from 2 Spark dataframesSparkR:levenshtein 来自 2 个 Spark 数据帧的 2 个变量之间的模糊字符串匹配
【发布时间】:2019-02-06 02:18:27
【问题描述】:

我有 2 个 Spark 数据帧

library(SparkR); library(magrittr)

df1 <- createDataFrame(data.frame(var1 = c("rat", "cat", "bat")))
df2 <- createDataFrame(data.frame(var2 = c("cat3", "bat1", "dog", "toy")))

我需要使用 SparkR 的 levenshtein 函数从不同的 Spark DataFrames df1 和 df2 模糊匹配不同长度的 var1 和 var2,以便得到所需的输出。

desired_df <- createDataFrame(data.frame(var2 = c("cat3", "bat1", "dog", "toy"),
                                  var3 = c("cat", "bat", NA_character_, NA_character_)))

我从以下代码开始:

df3 <- df2 %>% SparkR::mutate(dist = levenshtein(df2$var2, df1$var1))

但遇到错误:

org.apache.spark.sql.AnalysisException: Resolved attribute(s) var1#176 missing from var2#178 in operator !Project [var2#178, levenshtein(var2#178, var1#176) AS dist#181].;;
!Project [var2#178, levenshtein(var2#178, var1#176) AS dist#181]

请指教。

【问题讨论】:

    标签: r apache-spark levenshtein-distance sparkr sparklyr


    【解决方案1】:

    您的错误是引用了执行计划中不存在的表中的列。

    添加crossJoin 可以解决这个问题:

    dist_df <- df1 %>%
      crossJoin(df2) %>% 
      withColumn("dist", levenshtein(df1$var1, df2$var2)) 
    dist_df %>% head()
    
      var1 var2 dist              
    1  rat cat3    2
    2  rat bat1    2
    3  rat  dog    3
    4  rat  toy    3
    5  cat cat3    1
    6  cat bat1    2
    

    从这里您可以使用标准方法 (How to select the first row of each group?) 来查找最接近的匹配项,例如:

    best_matches <- dist_df %>% 
      groupBy("var2") %>% 
      agg(struct(dist_df$dist, dist_df$var1) %>% min() %>% alias("match"))
    
    threshold <- 1  # Maximum match distance to keep
    
    result <- best_matches %>% 
      select(
        best_matches$var2, 
        when(best_matches$match.dist <= threshold, best_matches$match.var1) %>% 
          alias("var1"))
    
    result %>% head()
    
      var2 var1
    1  dog <NA>
    2 bat1  bat
    3 cat3  cat
    4  toy <NA>
    

    请记住,这种方法效率很低。 Spark 提供了更好的选项 (Efficient string matching in Apache Spark),但这些选项尚未在 SparkR 中公开,并且仅在 sparklyr 中部分实现。

    如果您想保留所有记录,无论质量如何,只需删除when

    best_matches %>% select(best_matches$var2, best_matches$match.var1) %>% head()
    
      var2 var1
    1  dog  bat
    2 bat1  bat
    3 cat3  cat
    4  toy  bat
    

    【讨论】:

      猜你喜欢
      • 2013-12-28
      • 2017-12-27
      • 2019-09-12
      • 2014-12-11
      • 2021-08-22
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      • 2020-07-08
      相关资源
      最近更新 更多