web-dev-qa-db-fra.com

Exploser dans PySpark

J'aimerais transformer un DataFrame contenant des listes de mots en un DataFrame avec chaque mot dans sa propre ligne.

Comment faire exploser sur une colonne d'un DataFrame?

Voici un exemple de certaines de mes tentatives où vous pouvez supprimer le commentaire de chaque ligne de code et obtenir l’erreur répertoriée dans le commentaire suivant. J'utilise PySpark dans Python 2.7 avec Spark 1.6.1.

from pyspark.sql.functions import split, explode
DF = sqlContext.createDataFrame([('cat \n\n elephant rat \n rat cat', )], ['Word'])
print 'Dataset:'
DF.show()
print '\n\n Trying to do explode: \n'
DFsplit_explode = (
 DF
 .select(split(DF['Word'], ' '))
#  .select(explode(DF['Word']))  # AnalysisException: u"cannot resolve 'explode(Word)' due to data type mismatch: input to function explode should be array or map type, not StringType;"
#   .map(explode)  # AttributeError: 'PipelinedRDD' object has no attribute 'show'
#   .explode()  # AttributeError: 'DataFrame' object has no attribute 'explode'
).show()

# Trying without split
print '\n\n Only explode: \n'

DFsplit_explode = (
 DF 
 .select(explode(DF['Word']))  # AnalysisException: u"cannot resolve 'explode(Word)' due to data type mismatch: input to function explode should be array or map type, not StringType;"
).show()

S'il vous plaît des conseils

22
user1982118

explode et split sont des fonctions SQL. Les deux fonctionnent sur SQL Column. split prend comme second argument une expression régulière Java). Si vous souhaitez séparer les données sur des espaces blancs arbitraires, vous avez besoin de quelque chose comme ceci:

df = sqlContext.createDataFrame(
    [('cat \n\n elephant rat \n rat cat', )], ['Word']
)

df.select(explode(split(col("Word"), "\s+")).alias("Word")).show()

## +--------+
## |    Word|
## +--------+
## |     cat|
## |elephant|
## |     rat|
## |     rat|
## |     cat|
## +--------+
32
zero323

Pour fractionner les espaces et supprimer les lignes vides, ajoutez la clause where.

DF = sqlContext.createDataFrame([('cat \n\n elephant rat \n rat cat\nmat\n', )], ['Word'])

>>> (DF.select(explode(split(DF.Word, "\s")).alias("Word"))
       .where('Word != ""')
       .show())

+--------+
|    Word|
+--------+
|     cat|
|elephant|
|     rat|
|     rat|
|     cat|
|     mat|
+--------+
13
Alexander