我正在尝试打印包含嵌套值的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
答案 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()