r - SparkR:levenshtein 来自 2 个 Spark 数据帧的 2 个变量之间的模糊字符串匹配

标签 r apache-spark levenshtein-distance sparkr sparklyr

我有 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 DataFrame 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]

请指教。

最佳答案

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

添加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

关于r - SparkR:levenshtein 来自 2 个 Spark 数据帧的 2 个变量之间的模糊字符串匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52108843/

相关文章:

r - 打印脚本在 R 中运行的时间

r - 数字值包含逗号-如何使这些数字成为数字?

r - IQR 计算和表格

apache-spark - Spark/Python - 使用配置单元创建表失败并出现 ParseException

scala - 当对中的顺序不相关时,获取 RDD 中对的唯一值

python - 写一个Python方法根据字符串生成拼写错误

c# - 这个 Levenshtein 距离算法是否正确?

r - 按部分字符串匹配分组

apache-spark - 跨集群分布分区

java - 实现一个简单的 Trie 以进行高效的 Levenshtein 距离计算 - Java