web-dev-qa-db-fra.com

comment parcourir chaque ligne de dataFrame dans pyspark

Par exemple

sqlContext = SQLContext(sc)

sample=sqlContext.sql("select Name ,age ,city from user")
sample.show()

L’instruction ci-dessus imprime la totalité de la table sur le terminal, mais je souhaite accéder à chaque ligne de cette table à l’aide de pour ou pendant et effectuer d’autres calculs.

24
Arti Berde

Vous définiriez une fonction personnalisée et utiliseriez la carte.

def customFunction(row):

   return (row.name, row.age, row.city)

sample2 = sample.rdd.map(customFunction)

ou

sample2 = sample.rdd.map(lambda x: (x.name, x.age, x.city))

La fonction personnalisée serait alors appliquée à chaque ligne du cadre de données. Notez que sample2 sera une RDD et non une base de données.

La carte est nécessaire si vous souhaitez effectuer des calculs plus complexes. Si vous avez juste besoin d'ajouter une colonne dérivée, vous pouvez utiliser la variable withColumn, qui renvoie un cadre de données.

sample3 = sample.withColumn('age2', sample.age + 2)
33
David

Vous ne pouvez simplement pas. DataFrames, comme les autres structures de données distribuées, ne sont pas iterable et est accessible uniquement à l'aide d'une fonction dédiée et/ou de méthodes SQL.

Vous pouvez bien sûr collect 

for row in df.rdd.collect():
    do_something(row)

ou convertir toLocalIterator 

for row in df.rdd.toLocalIterator():
    do_something(row)

et itérer localement comme indiqué ci-dessus, mais il vaut mieux utiliser Spark.

21
zero323

En utilisant les interprétations de liste en python, vous pouvez rassembler une colonne entière de valeurs dans une liste en deux lignes seulement:

df = sqlContext.sql("show tables in default")
tableList = [x["tableName"] for x in df.rdd.collect()]

Dans l'exemple ci-dessus, nous renvoyons une liste de tables dans la base de données 'default', mais vous pouvez également l'adapter en remplaçant la requête utilisée dans sql ().

Ou plus abrégé:

tableList = [x["tableName"] for x in sqlContext.sql("show tables in default").rdd.collect()]

Et pour votre exemple de trois colonnes, nous pouvons créer une liste de dictionnaires, puis les parcourir dans une boucle for.

sql_text = "select name, age, city from user"
tupleList = [{name:x["name"], age:x["age"], city:x["city"]} 
             for x in sqlContext.sql(sql_text).rdd.collect()]
for row in tupleList:
    print("{} is a {} year old from {}".format(
        row["name"],
        row["age"],
        row["city"]))
6
aaronsteers

Si vous souhaitez appliquer quelque chose à chaque ligne d'un objet DataFrame, utilisez map. Cela vous permettra d'effectuer d'autres calculs sur chaque ligne. C'est l'équivalent de boucler sur l'ensemble du jeu de données de 0 à len(dataset)-1

Notez que cela renverra un PipelinedRDD, pas un DataFrame. 

2
Katya Handler

Essayez comme ça

result = spark.createDataFrame([('SpeciesId','int'), ('SpeciesName','string')],["col_name", "data_type"]); for f in result.collect(): print (f.col_name)
1
Bala cse

au dessus de

tupleList = [{name:x["name"], age:x["age"], city:x["city"]} 

devrait être 

tupleList = [{'name':x["name"], 'age':x["age"], 'city':x["city"]} 

pour name, age et city ne sont pas des variables mais simplement des clés du dictionnaire.

1
ten2the6