尝试将一个数据框的每一行与另一个数据框的某些行合并时的最合适的连接类型

时间:2020-07-24 01:48:27

标签: scala dataframe apache-spark

我遇到以下情况,但已经以非常低效的方式解决了该问题:

我有一个名为dfUniques的数据框,其中每一行包含与其他行不同的值(例如:1K行,但可能更多,甚至少于100行)。还有一个名为dfFull的数据帧,在该数据帧的某些行中可以找到与dfUniques中相同的值。 dfFulldfUniques大得多,并且列数是dfUniques的3倍。我想做的是找到dfFull中的所有行,其中与dfUniques相同的列具有与其中一行相同的值。因为目标是计算dfUniquesdfFull中有多少行。

我实现的方法是错误的(我认为),因为这需要花费很多时间,而且我正在使用collect()调用(而且我知道数据变大并不是最好的) 。这是我的代码:

dfUniques.collect().foreach{
  row => {
   val singlerowRDD = spark.createDataFrame(spark.sparkContext.parallelize(Seq(row)), myschema)
   val matching = dfFull
      .join(singlerow, columnsInCommon)
      .select(selColumns.head, selColumns.tail: _*)
   val matchingCount = matching.count()
   println("instances that matched\t" + matchingCount)

   if (matchingRBCount > 0){
        val dfAggr = matching.groupBy("name").avg(selColumns: _*)
        resultData = resultData.union(dfAggr)
  }
}

}

我认为一种好的方法应该使用一些join,但是我找不到最适合自己想要的方法。有什么建议吗? 我已经找到了这个(https://stackoverflow.com/a/51679966/5081366),但这并不是我的情况,因为该帖子尝试将一个数据框的每一行与另一个数据框的所有行连接起来,但是我只想获取与每个数据框匹配的行dfUniques行。好吧,我希望很清楚。

1 个答案:

答案 0 :(得分:1)

您是对的,加入是最好的方式。在您的情况下,“左半”将适用。您还可以从此处阅读各种类型的Spark Join-https://spark.apache.org/docs/2.4.0/api/python/pyspark.sql.html?highlight=join#pyspark.sql.DataFrame.join

tst= sqlContext.createDataFrame([(1,2),(1,3),(9,9),(2,4),(2,10),(3,5),(10,9),(3,6),(3,8),(7,9),(4,5),(19,1),(20,4),(22,3),(30,5),(67,4)],schema=['a','b'])
tst1 = sqlContext.createDataFrame([(1,2),(2,5),(7,6)],schema=['a','c'])
tst_res= tst.join(tst1,on='a',how='left_semi')

tst_res.show()
+---+---+
|  a|  b|
+---+---+
|  1|  2|
|  1|  3|
|  2|  4|
|  2| 10|
|  7|  9|
+---+---+