繁体   English   中英

如何在数据框中指向或选择单元格,Spark - Scala

[英]How to point or select a cell in a dataframe, Spark - Scala

我想找到2个单元格的时差。

使用 python 中的arrays ,我会做一个for loop st[i+1] - st[i]并将结果存储在某处。

我有这个按时间排序的数据框。 我怎么能用Spark 2Scala做到这一点,伪代码就足够了。

+--------------------+-------+
|                  st|   name|
+--------------------+-------+
|15:30               |dog    |
|15:32               |dog    |
|18:33               |dog    |
|18:34               |dog    |
+--------------------+-------+

就像是:

object Data1 {

  import org.apache.log4j.Logger
  import org.apache.log4j.Level

  Logger.getLogger("org").setLevel(Level.OFF)
  Logger.getLogger("akka").setLevel(Level.OFF)

  def main(args: Array[String]) : Unit = {
    implicit val spark: SparkSession =
      SparkSession
        .builder()
        .appName("Test")
        .master("local[1]")
        .getOrCreate()

    import org.apache.spark.sql.functions.col

    val rows = Seq(Row(1, 1), Row(1, 1), Row(1, 1))
    val schema = List(StructField("int1", IntegerType, true), StructField("int2", IntegerType, true))

    val someDF = spark.createDataFrame(
      spark.sparkContext.parallelize(rows),
      StructType(schema)
    )

    someDF.withColumn("diff", col("int1") - col("int2")).show()
  }
}

+----+----+----+
|int1|int2|diff|
+----+----+----+
|   1|   1|   0|
|   1|   1|   0|
|   1|   1|   0|
+----+----+----+

如果您特别想比较集合中的相邻元素,那么在 Scala 中,我会用它的尾部压缩集合,以提供一个包含相邻对的元组的集合。

不幸的是,RDD 或 DataFrames/Sets 上没有尾部方法

你可以这样做:

val a = myDF.rdd
val tail = myDF.rdd.zipWithIndex.collect{
  case (index, v) if index > 1 => v}

a.zip(tail).map{ case (l, r) => /* diff l and r st column */}.collect

如果diff name计算每个分区的滑动diff ,我将使用lag()窗口函数:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window

val df = Seq(
  ("a", 100), ("a", 120),
  ("b", 200), ("b", 240), ("b", 270)
).toDF("name", "value")

val window = Window.partitionBy($"name").orderBy("value")

df.
  withColumn("diff", $"value" - lag($"value", 1).over(window)).
  na.fill(0).
  orderBy("name", "value").
  show
// +----+-----+----+
// |name|value|diff|
// +----+-----+----+
// |   a|  100|   0|
// |   a|  120|  20|
// |   b|  200|   0|
// |   b|  240|  40|
// |   b|  270|  30|
// +----+-----+----+

另一方面,如果要在整个数据集上计算滑动diff ,则没有分区的窗口函数将无法缩放,因此我将求助于使用 RDD 的sliding()函数:

import org.apache.spark.sql.Row
import org.apache.spark.sql.types._
import org.apache.spark.mllib.rdd.RDDFunctions._

val rdd = df.rdd

val diffRDD = rdd.sliding(2).
  map{ case Array(x, y) => Row(y.getString(0), y.getInt(1), y.getInt(1) - x.getInt(1)) }

val headRDD = sc.parallelize(Seq(Row.fromSeq(rdd.first.toSeq :+ 0)))

val headDF = spark.createDataFrame(headRDD, df.schema.add("diff", IntegerType))
val diffDF = spark.createDataFrame(diffRDD, df.schema.add("diff", IntegerType))

val resultDF = headDF union diffDF
resultDF.show
// +----+-----+----+
// |name|value|diff|
// +----+-----+----+
// |   a|  100|   0|
// |   a|  120|  20|
// |   b|  200|  80|
// |   b|  240|  40|
// |   b|  270|  30|
// +----+-----+----+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM