为啥 Spark 不能从 HDFS 正确加载列? [复制]

Posted

技术标签:

【中文标题】为啥 Spark 不能从 HDFS 正确加载列? [复制]【英文标题】: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)。正如你所看到的,这些列是乱七八糟的。

【问题讨论】:

【参考方案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")),它可以工作。

【讨论】:

以上是关于为啥 Spark 不能从 HDFS 正确加载列? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

从 HDFS 加载数据 -Spark Scala [重复]

spark - 从HDFS加载文件并分析

为啥 pyspark sql 不能正确计算 group by 子句?

使用 thriftserver 和直线错误将数据从 hdfs 加载到 spark2.1 表中

使用 scala 从 HDFS 读取输入 xml 数据

使用 Spark 验证 CSV 文件列