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.
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)
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.
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"]))
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.
result = spark.createDataFrame([('SpeciesId','int'), ('SpeciesName','string')],["col_name", "data_type"]); for f in result.collect(): print (f.col_name)
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.