web-dev-qa-db-fra.com

Conversion de la colonne spark DataFrame en liste python

Je travaille sur un dataframe avec deux colonnes, mvv et count.

+---+-----+
|mvv|count|
+---+-----+
| 1 |  5  |
| 2 |  9  |
| 3 |  3  |
| 4 |  1  |

je voudrais obtenir deux liste contenant les valeurs MVV et la valeur de comptage. Quelque chose comme

mvv = [1,2,3,4]
count = [5,9,3,1]

J'ai donc essayé le code suivant: La première ligne devrait renvoyer une liste de rangées python. Je voulais voir la première valeur:

mvv_list = mvv_count_df.select('mvv').collect()
firstvalue = mvv_list[0].getInt(0)

Mais je reçois un message d'erreur avec la deuxième ligne:

AttributeError: getInt

66
a.moussa

Vous voyez, pourquoi cette façon que vous faites ne fonctionne pas. Tout d’abord, vous essayez d’obtenir un entier de type Row , le résultat de votre collecte est le suivant:

>>> mvv_list = mvv_count_df.select('mvv').collect()
>>> mvv_list[0]
Out: Row(mvv=1)

Si vous prenez quelque chose comme ça:

>>> firstvalue = mvv_list[0].mvv
Out: 1

Vous obtiendrez la valeur mvv. Si vous voulez toutes les informations du tableau, vous pouvez prendre quelque chose comme ceci:

>>> mvv_array = [int(row.mvv) for row in mvv_list.collect()]
>>> mvv_array
Out: [1,2,3,4]

Mais si vous essayez la même chose pour l'autre colonne, vous obtenez:

>>> mvv_count = [int(row.count) for row in mvv_list.collect()]
Out: TypeError: int() argument must be a string or a number, not 'builtin_function_or_method'

Cela est dû au fait que count est une méthode intégrée. Et la colonne porte le même nom que count. Une solution de contournement consiste à changer le nom de colonne de count en _count:

>>> mvv_list = mvv_list.selectExpr("mvv as mvv", "count as _count")
>>> mvv_count = [int(row._count) for row in mvv_list.collect()]

Mais cette solution de contournement n'est pas nécessaire, car vous pouvez accéder à la colonne à l'aide de la syntaxe du dictionnaire:

>>> mvv_array = [int(row['mvv']) for row in mvv_list.collect()]
>>> mvv_count = [int(row['count']) for row in mvv_list.collect()]

Et ça va enfin marcher!

96
Thiago Baldim

Après une doublure donne la liste que vous voulez.

mvv = mvv_count_df.select("mvv").rdd.flatMap(lambda x: x).collect()
67
Neo

Cela vous donnera tous les éléments sous forme de liste.

mvv_list = list(
    mvv_count_df.select('mvv').toPandas()['mvv']
)

Le code suivant vous aidera

mvv_count_df.select('mvv').rdd.map(lambda row : row[0]).collect()
11
Itachi

Sur mes données, j'ai obtenu ces points de repère:

>>> data.select(col).rdd.flatMap(lambda x: x).collect()

0.52 sec

>>> [row[col] for row in data.collect()]

0.271 sec

>>> list(data.select(col).toPandas()[col])

0.427 sec

Le résultat est le même

4
luminousmen

Si vous obtenez l'erreur ci-dessous:

AttributeError: l'objet 'list' n'a pas d'attribut 'collect'

Ce code va résoudre vos problèmes:

mvv_list = mvv_count_df.select('mvv').collect()

mvv_array = [int(i.mvv) for i in mvv_list]
3
anirban sen