web-dev-qa-db-fra.com

Comment obtenir la dernière ligne de DataFrame?

J'ai un DataFrame, le DataFrame a deux colonnes 'value' et 'timestamp', le 'timestmp' est ordonné, je veux obtenir la dernière ligne du DataFrame, que dois-je faire?

c'est mon entrée:

+-----+---------+
|value|timestamp|
+-----+---------+
|    1|        1|
|    4|        2|
|    3|        3|
|    2|        4|
|    5|        5|
|    7|        6|
|    3|        7|
|    5|        8|
|    4|        9|
|   18|       10|
+-----+---------+

voici mon code:

    val arr = Array((1,1),(4,2),(3,3),(2,4),(5,5),(7,6),(3,7),(5,8),(4,9),(18,10))
    var df=m_sparkCtx.parallelize(arr).toDF("value","timestamp")

c'est mon résultat attendu:

+-----+---------+
|value|timestamp|
+-----+---------+
|   18|       10|
+-----+---------+
6
mentongwu

Je voudrais simplement reduce:

df.reduce { (x, y) => 
  if (x.getAs[Int]("timestamp") > y.getAs[Int]("timestamp")) x else y 
}
3
Alper t. Turker

Essayez ça, ça marche pour moi.

df.orderBy($"value".desc).show(1)
9
Mimii Cheng

J'utiliserais simplement la requête qui - ordonne votre table par ordre décroissant - prend la 1ère valeur de cet ordre

df.createOrReplaceTempView("table_df")
query_latest_rec = """SELECT * FROM table_df ORDER BY value DESC limit 1"""
latest_rec = self.sqlContext.sql(query_latest_rec)
latest_rec.show()
4
Danylo Zherebetskyy

Le moyen le plus efficace consiste à reduce votre DataFrame. Cela vous donne une seule ligne que vous pouvez reconvertir en DataFrame, mais comme il ne contient qu'un seul enregistrement, cela n'a pas beaucoup de sens.

sparkContext.parallelize(
  Seq(
  df.reduce {
    (a, b) => if (a.getAs[Int]("timestamp") > b.getAs[Int]("timestamp")) a else b 
   } match {case Row(value:Int,timestamp:Int) => (value,timestamp)}
  )
)
.toDF("value","timestamp")
.show


+-----+---------+
|value|timestamp|
+-----+---------+
|   18|       10|
+-----+---------+

Cette solution est moins efficace (car elle doit être mélangée), mais plus courte:

df
.where($"timestamp" === df.groupBy().agg(max($"timestamp")).map(_.getInt(0)).collect.head)
1
Raphael Roth

Si votre colonne d'horodatage est unique et est en ordre croissant, il existe des moyens suivants pour obtenir la dernière ligne

println(df.sort($"timestamp", $"timestamp".desc).first())

// Output [1,1]

df.sort($"timestamp", $"timestamp".desc).take(1).foreach(println)

// Output [1,1]

df.where($"timestamp" === df.count()).show

Production:

+-----+---------+
|value|timestamp|
+-----+---------+
|   18|       10|
+-----+---------+

Sinon, créez une nouvelle colonne avec l'index et sélectionnez le dernier index comme ci-dessous

val df1 = spark.sqlContext.createDataFrame(
    df.rdd.zipWithIndex.map {
  case (row, index) => Row.fromSeq(row.toSeq :+ index)
},
StructType(df.schema.fields :+ StructField("index", LongType, false)))

df1.where($"timestamp" === df.count()).drop("index").show

Production:

+-----+---------+
|value|timestamp|
+-----+---------+
|   18|       10|
+-----+---------+
1
koiralo

Java:

Dataset<Row> sortDF = inputDF.orderBy(org.Apache.spark.sql.functions.col(config.getIncrementingColumn()).desc());
Row row = sortDF.first()
0
Suneel

Vous pouvez également utiliser cette fonction desc : Column desc(String columnName)

df.orderBy(desc("value")).show(1)

ce qui donne le même résultat que

df.orderBy($"value".desc).show(1)
0
Saurav Sahu