在没有标题的 Spark Dataframe 中读取 Hive 表

Posted

技术标签:

【中文标题】在没有标题的 Spark Dataframe 中读取 Hive 表【英文标题】:Reading Hive Tables in Spark Dataframe without header 【发布时间】:2017-11-22 11:12:39 【问题描述】:

我有以下 Hive 表:

select* from employee;
OK
abc     19      da
xyz     25      sa
pqr     30      er
suv     45      dr

当我在 spark(pyspark) 中读到这篇文章时:

df = hiveCtx.sql('select* from spark_hive.employee')
df.show()
+----+----+-----+
|name| age| role|
+----+----+-----+
|name|null| role|
| abc|  19|   da|
| xyz|  25|   sa|
| pqr|  30|   er|
| suv|  45|   dr|
+----+----+-----+

我最终在我的 spark DataFrame 中获得了标题。有没有简单的方法来删除它?

另外,在将表格读入 DataFrame 时我是否遗漏了一些东西(理想情况下我不应该得到正确的标题?)?

【问题讨论】:

【参考方案1】:

您必须从结果中删除标题。你可以这样做:

scala> val df = sql("select * from employee")
df: org.apache.spark.sql.DataFrame = [id: int, name: string ... 1 more field]

scala> df.show
+----+----+----+
|  id|name| age|
+----+----+----+
|null|name|null|
|   1| abc|  19|
|   2| xyz|  25|
|   3| pqr|  30|
|   4| suv|  45|
+----+----+----+

scala> val header = df.first()
header: org.apache.spark.sql.Row = [null,name,null]

scala> val data = df.filter(row => row != header) 
data: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [id: int, name: string ... 1 more field]

scala> data.show
+---+----+---+
| id|name|age|
+---+----+---+
|  1| abc| 19|
|  2| xyz| 25|
|  3| pqr| 30|
|  4| suv| 45|
+---+----+---+

谢谢。

【讨论】:

这不是他所要求的,当他在 hive 中触发查询时,他得到了正确的结果,但是当使用 hive 上下文在 spark 中触发相同的查询时得到错误的结果 我认为默认情况下配置单元会删除标头,在 Spark 中我们必须删除标头。 不,情况并非如此,使用 spark 和 hive 近一年的其他事情 \ 我在 pyspark 中试过这个。 dfemp = df.filter(lambda line: line!=header) 这给了我错误:条件应该是字符串或列 不是最优雅的方式,但这适用于 pyspark: rddWithoutHeader = dfemp.rdd.filter(lambda line: line!=header) dfnew = sqlContext.createDataFrame(rddWithoutHeader)【参考方案2】:

您可以使用skip.header.line.count 跳过此标头。您也可以在创建表时指定相同的值。例如:

create external table testtable ( id int,name string, age int)
row format delimited .............
tblproperties ("skip.header.line.count"="1");

之后加载数据,然后检查您的查询,希望您能得到预期的输出。

【讨论】:

我在使用 hive 创建表时这样做了,但我仍然使用 spark 获得标题【参考方案3】:

不是最优雅的方式,但这适用于 pyspark:

rddWithoutHeader = dfemp.rdd.filter(lambda line: line!=header) 
dfnew = sqlContext.createDataFrame(rddWithoutHeader)

【讨论】:

以上是关于在没有标题的 Spark Dataframe 中读取 Hive 表的主要内容,如果未能解决你的问题,请参考以下文章

在 Scala 中使用来自另一个没有数组列的 DataFrame 的数组类型列创建 Spark DataFrame 的有效方法是啥?

在 Spark DataFrame SQL 中获取没有路径的文件名

查看 Spark Dataframe 列的内容

更改 Spark Dataframe 的架构

使用scala在Spark中转置DataFrame而不进行聚合

如何在 pyspark 中将 DenseMatrix 转换为 spark DataFrame?