比较两个数据帧以查找spark中的子字符串

时间:2017-03-21 15:50:11

标签: scala apache-spark dataframe

我有三个数据框,字典,SourceDictionary和MappedDictionary。字典和SourceDictionary只有一列,比如String。具有百万条记录的字典是MappedDictionary的子集(大约10M条记录),MappedDictionary中的每条记录都是字典的子字符串。所以,我需要将带有SourceDictionary的ditionary映射到MappedDictionary。   示例:

Records in ditionary : BananaFruit, AppleGreen
Records in SourceDictionary : Banana,grape,orange,lemon,Apple,...

要在MappedDictionary中映射的记录(包含两列):

BananaFruit Banana
AppleGreen Apple

我计划在java中做两个for循环并进行子串操作,但问题是100万* 1000万= 10万亿次迭代   另外,我无法像for循环一样迭代数据帧 有人可以为在Dataframe中进行迭代并执行子串操作的方法提供解决方案吗?   抱歉我的英语不好,我是非本地人 感谢stackoverflow社区成员提前: - )

1 个答案:

答案 0 :(得分:1)

虽然你在sourceDictionary中有数百万条记录,因为它只有一列将它广播到每个节点,但不会占用太多内存,它会加快总体性能。

import org.apache.spark.broadcast.Broadcast
import org.apache.spark.sql.catalyst.encoders.RowEncoder

//Assuming the schema names
val SourceDictionarySchema = StructType(StructField("value",StringType,false)) 
val dictionarySchema = StructType(StructField("value",StringType,false))
val MappedDictionary = StructType(StructField("value",StringType,false), StructField("key",StringType,false))

val sourceDictionaryBC = sc.broadcast(
   sourceDictionary.map(row =>
      row.getAs[String]("value")
   ).collect.toList
)

val MappedDictionaryN = dictionary.map(row =>
   val value = row.getAs[String]("value")
   val matchedKey = sourceDictionaryBC.value.find(value.contains)

   Seq(value, matchedKey.orNull)
)(RowEncoder(MappedDictionary))

在此之后,您将拥有所有新的映射记录。如果你想将它与现有的MappedDictionary结合起来,那就做一个简单的联合。

MappedDictionaryN.union(MappedDictionary)