Scala 如何循环通过Spark数据帧

Scala 如何循环通过Spark数据帧,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,如何循环通过Spark数据帧? 我有一个数据框架,包括: 时间、id、方向 10,4,真//这里4进入-->(4,) 20,5,对//这里5进入-->(4,5) 34,5,False//这里有5片叶子-->(4,) 67,6,对//这里6进入-->(4,6) 78,6,False//这里有6个叶子-->(4,) 99,4,False//这里有4片叶子-->() 它是按时间排序的,现在我想一步一步累积有效的ID。ID在方向上输入==True,在方向上退出==False 因此,生成的RDD应该如下

如何循环通过Spark数据帧? 我有一个数据框架,包括:

时间、id、方向
10,4,真//这里4进入-->(4,)
20,5,对//这里5进入-->(4,5)
34,5,False//这里有5片叶子-->(4,)
67,6,对//这里6进入-->(4,6)
78,6,False//这里有6个叶子-->(4,)
99,4,False//这里有4片叶子-->()
它是按时间排序的,现在我想一步一步累积有效的ID。ID在方向上输入==True,在方向上退出==False

因此,生成的RDD应该如下所示

时间,有效的\u id
(10, (4,))
(20, (4,5))
(34, (4,))
(67, (4,6))
(78, (4,)
(99, ())
我知道这不会并行化,但df没有那么大。那么如何在Spark/Scala中实现这一点呢?

如果数据很小(“但df没有那么大”),我只会使用Scala集合进行收集和处理。如果类型如下所示:

df.printSchema
root
 |-- time: integer (nullable = false)
 |-- id: integer (nullable = false)
 |-- direction: boolean (nullable = false)
您可以收集:

val data = df.as[(Int, Int, Boolean)].collect.toSeq
scanleet

val result = data.scanLeft((-1, Set[Int]())){ 
  case ((_, acc), (time, value, true)) => (time, acc + value)
  case ((_, acc), (time, value, false))  => (time, acc - value)
}.tail
如果数据很小(“但df没有那么大”),我只会使用Scala集合进行收集和处理。如果类型如下所示:

df.printSchema
root
 |-- time: integer (nullable = false)
 |-- id: integer (nullable = false)
 |-- direction: boolean (nullable = false)
您可以收集:

val data = df.as[(Int, Int, Boolean)].collect.toSeq
scanleet

val result = data.scanLeft((-1, Set[Int]())){ 
  case ((_, acc), (time, value, true)) => (time, acc + value)
  case ((_, acc), (time, value, false))  => (time, acc - value)
}.tail

不建议scala开发人员使用
var
,但我仍然使用
var

var collectArray = Array.empty[Int]
df.rdd.collect().map(row => {
  if(row(2).toString.equalsIgnoreCase("true")) collectArray = collectArray :+ row(1).asInstanceOf[Int]
  else collectArray = collectArray.drop(1)
  (row(0), collectArray.toList)
})
这应该会给你一个结果

(10,List(4))
(20,List(4, 5))
(34,List(5))
(67,List(5, 6))
(78,List(6))
(99,List())

不建议scala开发人员使用
var
,但我仍然使用
var

var collectArray = Array.empty[Int]
df.rdd.collect().map(row => {
  if(row(2).toString.equalsIgnoreCase("true")) collectArray = collectArray :+ row(1).asInstanceOf[Int]
  else collectArray = collectArray.drop(1)
  (row(0), collectArray.toList)
})
这应该会给你一个结果

(10,List(4))
(20,List(4, 5))
(34,List(5))
(67,List(5, 6))
(78,List(6))
(99,List())

假设相应数据帧的名称为
someDF
,然后执行以下操作:

val df1 = someDF.rdd.collect.iterator;
   while(df1.hasNext) 
   {
       println(df1.next);
   }

假设相应数据帧的名称为
someDF
,然后执行以下操作:

val df1 = someDF.rdd.collect.iterator;
   while(df1.hasNext) 
   {
       println(df1.next);
   }