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|
+-----+---------+
Je voudrais simplement reduce
:
df.reduce { (x, y) =>
if (x.getAs[Int]("timestamp") > y.getAs[Int]("timestamp")) x else y
}
Essayez ça, ça marche pour moi.
df.orderBy($"value".desc).show(1)
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()
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)
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|
+-----+---------+
Java:
Dataset<Row> sortDF = inputDF.orderBy(org.Apache.spark.sql.functions.col(config.getIncrementingColumn()).desc());
Row row = sortDF.first()
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)