Spark将单个数据帧加入到Dataframe集合中

时间:2018-03-02 20:56:21

标签: scala spark-dataframe

我正在努力想出一个优雅的解决方案,将单个数据帧连接到1到N个相关数据帧的单独序列。初步尝试:

  val sources = program.attributes.map(attr => {
    spark.read
      .option("header", value = true)
      .schema(program.GetSchema(attr))
      .csv(s"${program.programRawHdfsDirectory}/${attr.sourceFile}")
  })
  val rawDf: DataFrame = sources.reduce((df1, df2) => df1.join(df2, program.dimensionFields, "full"))

  // Full of fail:
  val fullDf: DataFrame = program.dimensions.filter(d => d.hierarchy != "RAW").reduceLeft((d1, _) => {
    val hierarchy = spark.read.parquet(d1.hierarchyLocation).where(d1.hierarchyFilter)
    rawDf.join(hierarchy, d1.hierarchyJoin)
  })

  fullDf.selectExpr(program.outputFields:_*).write.parquet(program.programEtlHdfsDirectory)

reduceLeft的想法不起作用,因为我正在迭代配置对象的集合(维度属性),但我希望从每次迭代返回的是一个数据帧。错误是类型不匹配,这并不奇怪。

问题的核心是我有1到N个“维”对象,它们定义了如何加载现有的层次结构表,以及如何将该表连接到我之前创建的“原始”数据帧。

任何想法如何在没有某种可怕的黑客的情况下创建这些联接?

更新

我想知道这可行吗?我在每个层次结构数据框中都有一个公共字段名称。如果我重命名这个公共字段以匹配我的“原始”数据帧中的相应列,我可以在折叠中执行连接而不显式调用列吗? Spark会默认使用匹配的名称吗?

  val rawDf = sources.reduce((df1, df2) => df1.join(df2, program.dimensionFields, "full"))

  val hierarchies = program.dimensions.map(dim => {
    spark.read.parquet(dim.hierarchyLocation).where(dim.hierarchyFilter).withColumnRenamed("parent_hier_cd", dim.columnName)
  })
  val fullDf = hierarchies.foldLeft(rawDf) { (df1, df2) => df1.join(df2) }

更新2

不,这不起作用。 Spark尝试交叉连接。

1 个答案:

答案 0 :(得分:0)

出于我的目的,我只需要在生成层次结构集时返回一个元组:

  val hierarchies = program.dimensions.map(dim => {
    val hierarchy = spark.read.parquet(dim.hierarchyLocation).where(dim.hierarchyFilter).alias(dim.hierarchy.toLowerCase)
    (dim, hierarchy)
  })

然后,当我将它们折叠到rawDf时,我有构建连接所需的元数据。