【问题标题】:How to load data into spark dataframe from text file without knowing the schema of the data?如何在不知道数据架构的情况下将数据从文本文件加载到 spark 数据框中?
【发布时间】:2018-11-22 18:27:39
【问题描述】:

我在 hadoop 中有一个文本文件,我需要使用 spark java api 使用它的第二列对其进行排序。我正在使用数据框,但我不确定它的列。 它可能有动态列,这意味着我不知道确切的列数。

我该如何继续?请帮帮我。

提前致谢。

【问题讨论】:

  • 你有没有尝试过?
  • 我尝试拆分它,然后尝试使用交换技术进行排序,但没有帮助。
  • 你能分享一些文本文件的行吗?
  • 你是怎么分裂的?我的意思是什么是分隔符......它是逗号分隔的吗?如果是逗号分隔,那么您可以使用 spark csv 在第二列创建数据框和 df.sort。无需担心架构。转换数据框后,df schema 是您的数据架构
  • 序列时间戳值标签。这是示例行,我想使用作为时间戳的第二列对其进行排序。我可以通过手动提及架构来使用第二列进行排序。但问题是数据可能包含或多或少的列数,但第二列将始终相同。输入数据是制表符分隔的文件。

标签: java apache-spark apache-spark-sql


【解决方案1】:

第一件事是我试图在 scala(不是 java)中给出一个 csv 示例

您可以使用 Spark csv api 创建数据框并根据您想要的任何列进行排序。 如果您有任何限制,请参阅以下方式。

固定列数:

从下面的固定列数示例开始.. 你可以按照这个例子。

ebay.csv 的数据在哪里:

“8213034705,95,2.927373,jake7870,0,95,117.5,xbox,3”

//  SQLContext entry point for working with structured data
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
// this is used to implicitly convert an RDD to a DataFrame.
import sqlContext.implicits._
// Import Spark SQL data types and Row.
import org.apache.spark.sql._

//define the schema using a case class
case class Auction(auctionid: String, bid: Float, bidtime: Float, bidder: String, bidderrate: Integer, openbid: Float, price: Float, item: String, daystolive: Integer)


 val auction = sc.textFile("ebay.csv").map(_.split(",")).map(p => 
Auction(p(0),p(1).toFloat,p(2).toFloat,p(3),p(4).toInt,p(5).toFloat,p(6).toFloat,p(7),p(8).toInt )).toDF()

// Display the top 20 rows of DataFrame 
auction.show()
// auctionid  bid   bidtime  bidder         bidderrate openbid price item daystolive
// 8213034705 95.0  2.927373 jake7870       0          95.0    117.5 xbox 3
// 8213034705 115.0 2.943484 davidbresler2  1          95.0    117.5 xbox 3 …


// Return the schema of this DataFrame
auction.printSchema()
root
 |-- auctionid: string (nullable = true)
 |-- bid: float (nullable = false)
 |-- bidtime: float (nullable = false)
 |-- bidder: string (nullable = true)
 |-- bidderrate: integer (nullable = true)
 |-- openbid: float (nullable = false)
 |-- price: float (nullable = false)
 |-- item: string (nullable = true)
 |-- daystolive: integer (nullable = true)

auction.sort("auctionid") // this will sort first column i.e auctionid

可变列数(since Case class with Array parameter is possible):

您可以使用如下伪代码,其中前 4 个元素是固定的,其余的都是可变数组...

由于您只被插入以对第二列进行排序,因此这将起作用,并且所有其他数据都将存在于该特定行的数组中,以供以后使用。

case class Auction(auctionid: String, bid: Float, bidtime: Float, bidder: String, variablenumberofColumnsArray:String*)

 val auction = sc.textFile("ebay.csv").map(_.split(",")).map(p => 
Auction(p(0),p(1).toFloat,p(2).toFloat,p(3),p(4).toInt, VariableNumberOfColumnsArray or any complex type like Map ).toDF()

    auction.sort("auctionid") // this will sort first column i.e auctionid

【讨论】:

  • 非常感谢。我会用 Java 试试这个。
  • 好的,它肯定可以工作如果你对答案没问题,你可以作为所有者接受答案
  • 对于已知的列号我可以做到,但对于未知的列号会遇到困难。列数。
  • 好的,您添加到 Array 或 List 了吗?前 4 或 5 个 cols 您可以使用固定数据类型,即 5...n 将进入一个数组。就这些
  • 是的,我正在尝试。
猜你喜欢
  • 2020-11-12
  • 2018-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
相关资源
最近更新 更多