如何在不转换为火花数据集的情况下遍历数据框?

Posted

技术标签:

【中文标题】如何在不转换为火花数据集的情况下遍历数据框?【英文标题】:How to iterate through dataframe without converting to dataset in spark? 【发布时间】:2019-03-28 18:09:06 【问题描述】:

我有一个要迭代的数据框,但我不想将数据框转换为数据集。 我们必须将 spark scala 代码转换为 pyspark,而 pyspark 不支持数据集。

我通过转换为数据集尝试了以下代码

data in file:

abc,a
mno,b
pqr,a
xyz,b

val a = sc.textFile("<path>")

//creating dataframe with column AA,BB

val b = a.map(x => x.split(",")).map(x =>(x(0).toString,x(1).toString)).toDF("AA","BB") 

b.registerTempTable("test")

case class T(AA:String, BB: String)

//creating dataset from dataframe

val d = b.as[T].collect       

d.foreach x=>
    var m = spark.sql(s"select * from test where BB = '$x.BB'")
    m.show()


Without converting to dataset it gives error i.e. with

val d = b.collect

d.foreach x=>
    var m = spark.sql(s"select * from test where BB = '$x.BB'")
    m.show()

它给出错误: 错误:值 BB 不是 org.apache.spark.sql.ROW 的成员

【问题讨论】:

以下是在 Scala 中,但尝试使用 filter 参数。您无需更改数据框。这个想法是您将 DF1 更改为 Array 并检查数组元素是否在数据框中。要逐个检查元素,您将使用循环机制逐个检查元素。 val bArray = b.selectExpr("BB").rdd.map(x=&gt;x.mkString).collect var iterator = 1 var m = b while(iterator &lt;= bArray.length) m = b.filter($"BB".isin(bArray(iterator - 1)) m.collect iterator = iterator + 1 【参考方案1】:

您不能像上面代码中给出的那样循环数据帧。使用dataframe的rdd.collect循环dataframe。

import spark.implicits._
val df = Seq(("abc","a"), ("mno","b"), ("pqr","a"),("xyz","b")).toDF("AA", "BB")
df.registerTempTable("test")
df.rdd.collect.foreach(x => 
     val BBvalue = x.mkString(",").split(",")(1)
     var m = spark.sql(s"select * from test where BB = '$BBvalue'")
     m.show()
)

在循环中,我使用mkString 将 rdd 行转换为字符串,然后用逗号分割列值,并使用列的索引来访问该值。例如,在上面的代码中我使用了(1),这意味着列BB的列索引是2。

如果您有任何问题,请告诉我。

【讨论】:

以上是关于如何在不转换为火花数据集的情况下遍历数据框?的主要内容,如果未能解决你的问题,请参考以下文章

如何在火花上将json字符串转换为数据帧

如何在火花中将rdd对象转换为数据框

如何在不使用和拆分测试集的情况下将我的数据集拆分为训练和验证?

计算火花数据框中的字数

如何在火花中遍历数据集列?

如何在不使用数据框的情况下将一行分解为多行?