【问题标题】:Why can't Spark properly load columns from HDFS? [duplicate]为什么 Spark 不能从 HDFS 正确加载列? [复制]
【发布时间】:2019-01-16 12:46:28
【问题描述】:

下面我提供了我的架构和用于从 hdfs 中的分区读取的代码。

一个分区的例子可以是这个路径:/home/maria_dev/data/key=key/date=19 jan(当然在这个文件夹里面有一个包含cnt的csv文件)

因此,我拥有的数据按keydate 列进行分区。

当我像下面这样阅读时,列未正确阅读,因此cnt 被读入date,反之亦然。

我该如何解决这个问题?

private val tweetSchema = new StructType(Array(
    StructField("date", StringType, nullable = true),
    StructField("key", StringType, nullable = true),
    StructField("cnt", IntegerType, nullable = true)
  ))

// basePath example: /home/maria_dev/data
// path example: /home/maria_dev/data/key=key/data=19 jan
private def loadDF(basePath: String, path: String, format: String): DataFrame = {
    val df = spark.read
      .schema(tweetSchema)
      .format(format)
      .option("basePath", basePath)
      .load(path)
    df
}

我尝试将它们在架构中的顺序从 (date, key, cnt) 更改为 (cnt, key, date),但这没有帮助。

我的问题是,当我调用 union 时,它会附加 2 个数据帧:

  • df1:{(key: 1, date: 2)}
  • df2:{(date: 3, key: 4)}

像这样进入最终数据框:{(key: 1, date: 2), (date: 3, key: 4)}。正如你所看到的,这些列是乱七八糟的。

【问题讨论】:

    标签: apache-spark apache-spark-sql


    【解决方案1】:

    架构应按以下顺序排列:

    • 数据文件中存在的列本身 - 如果是 CSV,则按从左到右的自然顺序排列。
    • 分区使用的列与目录结构定义的顺序相同。

    所以在你的情况下,正确的顺序是:

    new StructType(Array(
      StructField("cnt", IntegerType, nullable = true),
      StructField("key", StringType, nullable = true),
      StructField("date", StringType, nullable = true)
    ))
    

    【讨论】:

      【解决方案2】:

      事实证明一切都被正确读取了。

      所以,现在,我不使用df1.union(df2),而是使用df1.select("key", "date").union(df2.select("key", "date")),它可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-08
        • 2019-07-23
        • 1970-01-01
        • 1970-01-01
        • 2010-10-13
        • 1970-01-01
        • 2015-12-31
        • 2019-05-26
        相关资源
        最近更新 更多