web-dev-qa-db-fra.com

Comment sélectionner la dernière ligne et aussi comment accéder à PySpark dataframe par index?

A partir d'un dataframe PySpark SQL comme 

name age city
abc   20  A
def   30  B

Comment obtenir la dernière ligne (comme par df.limit (1), je peux obtenir la première ligne de dataframe dans une nouvelle dataframe).

Et comment puis-je accéder aux lignes du cadre de données par index.like numéro de ligne. 12 ou 200.

Dans les pandas je peux faire

df.tail(1) # for last row
df.ix[rowno or index] # by index
df.loc[] or by df.iloc[]

Je suis simplement curieux de savoir comment accéder à pyspark dataframe de telle manière ou de manière alternative.

Merci

7
Satya

Comment obtenir la dernière ligne.

Manière longue et laide qui suppose que toutes les colonnes sont odibles:

from pyspark.sql.functions import (
    col, max as max_, struct, monotonically_increasing_id
)

last_row = (df
    .withColumn("_id", monotonically_increasing_id())
    .select(max(struct("_id", *df.columns))
    .alias("tmp")).select(col("tmp.*"))
    .drop("_id"))

Si toutes les colonnes ne peuvent pas être commandées, vous pouvez essayer:

with_id = df.withColumn("_id", monotonically_increasing_id())
i = with_id.select(max_("_id")).first()[0]

with_id.where(col("_id") == i).drop("_id")

Remarque. Il y a une fonction last dans pyspark.sql.functions`o.a.s.sql.functions mais considérant la description des expressions correspondantes ce n'est pas un bon choix ici.

comment puis-je accéder aux lignes de la base de données par index.like

Vous ne pouvez pas. Spark DataFrame et accessible par index. Vous pouvez ajouter des index en utilisant zipWithIndex et filtrer plus tard. Rappelez-vous simplement cette opération _/O(N)

5
zero323

Comment obtenir la dernière ligne.

Si vous avez une colonne que vous pouvez utiliser pour commander un cadre de données, par exemple "index", un moyen simple d'obtenir le dernier enregistrement consiste à utiliser SQL: 1) ordonnez votre table par ordre décroissant et 2) prenez 1ère valeur de cette commande

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

Et comment puis-je accéder aux lignes du cadre de données par index.like numéro de ligne. 12 ou 200.

De manière similaire, vous pouvez obtenir un enregistrement dans n'importe quelle ligne

row_number = 12
df.createOrReplaceTempView("table_df")
query_latest_rec = """SELECT * FROM (select * from table_df ORDER BY index ASC limit {0}) ord_lim ORDER BY index DESC limit 1"""
latest_rec = self.sqlContext.sql(query_latest_rec.format(row_number))
latest_rec.show()

Si vous n'avez pas de colonne "index", vous pouvez la créer en utilisant

from pyspark.sql.functions import monotonically_increasing_id

df = df.withColumn("index", monotonically_increasing_id())
3
Danylo Zherebetskyy
from pyspark.sql import functions as F

expr = [F.last(col).alias(col) for col in df.columns]

df.groupBy().agg(*expr)

Juste un conseil: On dirait que vous avez toujours la mentalité de quelqu'un qui travaille avec des pandas ou R. Spark est un paradigme différent dans la façon dont nous travaillons avec les données. Vous n’accédez plus aux données à l’intérieur de cellules individuelles, maintenant vous travaillez avec des morceaux entiers de celles-ci. Si vous continuez à collecter des choses et à faire des actions, comme vous venez de le faire, vous perdez tout le concept de parallélisme fourni par l'étincelle. Jetez un coup d'œil au concept de transformation par rapport aux actions dans Spark.

2

Utilisez ce qui suit pour obtenir une colonne d'index contenant des entiers consécutifs et à croissance monotone, uniques, qui est non comment monotonically_increasing_id() fonctionne. Les index seront ascendants dans le même ordre que colName de votre DataFrame.

import pyspark.sql.functions as F
from pyspark.sql.window import Window as W

window = W.orderBy('colName').rowsBetween(W.unboundedPreceding, W.currentRow)

df = df\
 .withColumn('int', F.lit(1))\
 .withColumn('index', F.sum('int').over(window))\
 .drop('int')\

Utilisez le code suivant pour examiner la fin ou la dernière rownums du DataFrame.

rownums = 10
df.where(F.col('index')>df.count()-rownums).show()

Utilisez le code suivant pour examiner les lignes de start_row à end_row le DataFrame. 

start_row = 20
end_row = start_row + 10
df.where((F.col('index')>start_row) & (F.col('index')<end_row)).show()

zipWithIndex() est une méthode RDD qui renvoie des nombres entiers croissants monotones, uniques et consécutifs, mais semble être beaucoup plus lente à implémenter de manière à pouvoir revenir à votre DataFrame d'origine modifié avec une colonne id.

0
Clay