连接多个数据框的功能方式

时间:2018-10-24 22:29:48

标签: scala apache-spark

我正在学习Scala中的Spark,源于严重的Python滥用,我得到了java.lang.NullPointerException,因为我是以python的方式工作的。

我说每个3x形状为4x2的数据帧,第一列始终是索引0、1、2、3,第二列是某种二进制特征。最终目标是拥有一个4x4数据帧,其中包含所有单个数据帧的连接。在python中,我先定义一些主df,然后在中间的df上循环,在每个循环中将结果联接的数据帧分配给主数据帧变量名(丑陋):

dataframes = [temp1, temp2, temp3]
df = pd.DataFrame(index=[0,1,2,3]) # Master df
for temp in dataframes:
    df = df.join(temp)

在Spark中,这种方法不能很好地发挥作用: q = "select * from table" val df = sql(q)很明显

scala> val df = df.join(sql(q))
<console>:33: error: recursive value df needs type
       val df = df.join(sql(q))

好吧:

scala> val df:org.apache.spark.sql.DataFrame = df.join(sql(q))
java.lang.NullPointerException
  ... 50 elided

我认为我很可能没有按照功能方式进行操作。所以我尝试了(最丑!):

scala> :paste
// Entering paste mode (ctrl-D to finish)

    sql(q).
      join(sql(q), "device_id").
      join(sql(q), "device_id").
      join(sql(q), "device_id")

    // Exiting paste mode, now interpreting.

    res128: org.apache.spark.sql.DataFrame = [device_id: string, devtype: int ... 3 more fields]

这看起来很丑陋,不雅和初学者。实现此目标的适当的功能性Scala方法是什么?

2 个答案:

答案 0 :(得分:2)

foldLeft

val dataframes: Seq[String] = ???
val df: Dataset[Row] = ???

dataframes.foldLeft(df)((acc, q) => acc.join(sql(q)))

如果您正在寻找与您的Python代码等效的命令:

var dataframes: Seq[String] = ???  // IMPORTANT: var
for (q <- dataframes ) { df = df.join(sql(q)) }

答案 1 :(得分:1)

更简单

val dataframes: Seq[String] = ???
dataframes.reduce(_ join _)