Spark:从嵌套DataFrame中打印元素

时间:2015-12-02 09:26:57

标签: scala apache-spark dataframe

我正在尝试打印包含嵌套值的DataFrame中的特定元素:

这是我得到的Spark SQL DataFrame

scala>result
org.apache.spark.sql.DataFrame = [P1: struct<t1:tinyint,t2:tinyint,t3:smallint,t4:int>, P2:struct<k1:tinyint,k2:int>]

它包含:

scala>result.take(3).foreach(println)
[[15,78,60,1111111],[10,7525619]]
[[15,78,60,2222222],[10,7525620]]
[[15,78,60,3333333],[10,7525621]]

如何只打印第一个结构中的第二个和第三个字段?

我试过了:

scala>result.take(3).foreach(l => printf("Num: %d-%d\n", l(0,2),l(0,3))) 

并收到错误。error: too many arguments for method apply: (i: Int)Any in trait Row

1 个答案:

答案 0 :(得分:1)

基于索引的访问

result.select("p1._2", "p1._3").show()

使用案例类

您可以预先使用case class

case class A(a1: Int, a2: Int, a3: Int, a4: Int)
case class B(b1: Int, b2: Int)
case class Record(a: A, b: B)

通过为嵌套结构和值提供有意义的名称来避免基于索引的访问。

然后定义数据框

val df = sc.parallelize(
  Seq(
    Record(A(15, 78, 60, 1111111), B(10, 7525619)),
    Record(A(15, 78, 60, 1111111), B(10, 7525619)))).toDF()

现在

df.select($"a.a2", $"a.a3").show()

df.registerTempTable("df")
sqlContext.sql("select a.a2, a.a3 from df").show()

作为替代方案,使用RDD

val rdd = sc.parallelize(
  Seq(
    Record(A(15, 78, 60, 1111111), B(10, 7525619)),
    Record(A(15, 78, 60, 1111111), B(10, 7525619))))

然后您可以map直接case class

rdd.map {
  rec =>
    (rec.a.a2, rec.a.a3)
}.collect()