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
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).
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())
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.
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.