Scala 在Spark DataFrame的列中搜索字符串的最佳方法
我正在使用ApacheSpark2.2和Scala2.11 我有一个字符串,我从中创建1-gram、2-gram和3-gram。之后,我尝试在数据帧中搜索这些值。现在这个过程发生了很多次,因为整个Spark工作需要很多时间。我该怎么想呢 以下是代码片段:Scala 在Spark DataFrame的列中搜索字符串的最佳方法,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我正在使用ApacheSpark2.2和Scala2.11 我有一个字符串,我从中创建1-gram、2-gram和3-gram。之后,我尝试在数据帧中搜索这些值。现在这个过程发生了很多次,因为整个Spark工作需要很多时间。我该怎么想呢 以下是代码片段: // creating the n-grams val vNGrams = for (i <- 1 to 3) yield sampleString.trim.split(" ").sliding(i).map(p => p.mkS
// creating the n-grams
val vNGrams = for (i <- 1 to 3) yield sampleString.trim.split(" ").sliding(i).map(p => p.mkString(" "))
// converting them to a single array as above code generates three different iterators for different ngrams
val z = vNGrams.map(itr => itr.toArray).flatten.toArray
for (i <- 0 to z.length-1) {
val df = vSomeTable.select("COUNTRY_CODE").where(upper(col("ZIPCODE")) === z(i).toUpperCase)
if(df.count.toInt > 0) {
countryCode = df.take(1)(0)(0).toString
return countryCode
}
}
//创建n-grams
val vNGrams=for(i p.mkString(“”)
//如上所述,将它们转换为单个数组,代码会为不同的NGRAM生成三个不同的迭代器
valz=vNGrams.map(itr=>itr.toArray).flatten.toArray
对于(i 0){
countryCode=df.take(1)(0)(0).toString
返回国家代码
}
}
在Spark UI中,我可以看到这些count
和take
作业需要时间。此代码段至少运行了20k次,而且vSomeTable
是一个具有41k行的数据帧
如果您需要更多信息,请告诉我,或者我可以用更少的时间以不同的方式完成相同的工作。请取消for循环,改用单个作业,而不是多个Spark作业。另外,避免同时使用
df.count
和df.take
和limit 1
以避免提前退出
val z = vNGrams.flatten.map(_.toUpperCase).toArray
val rows = vSomeTable
.select("COUNTRY_CODE")
.where(upper(col("ZIPCODE")).isInCollection(z))
.limit(1)
.collect()
if (!rows.isEmpty) {
...
}
isInCollection
来自spark 2.4,我使用的是2.2。我应该使用什么函数来代替它呢?@GadaaDhaariGeekisInCollection
仅仅是一个方便的包装器,用于isin(z:*)
,它从1.5.0开始就可以使用。是的,我仅从网络上了解到这一点。不管怎样,谢谢。但问题还是一样。现在,collect()。获取行后,我要做的是将COUNTRY_代码作为字符串返回。这方面有什么帮助吗?听起来不错,collect
是应该花费时间的地方,可以说它比原始版本快。由于存在limit 1
,因此可能最容易将国家/地区代码收集到选项[String]
so…limit(1)。选择($“国家/地区代码”).collect().collectFirst{case Row(cc:String)=>cc}