web-dev-qa-db-fra.com

Spark Error: zéro argument attendu pour la construction de ClassDict (pour numpy.core.multiarray._reconstruct)

J'ai une base de données dans Spark dans laquelle l'une des colonnes contient un tableau. Maintenant, j'ai écrit un fichier UDF distinct qui convertit le tableau en un autre tableau contenant uniquement des valeurs distinctes. Voir exemple ci-dessous:

Ex: [24,23,27,23] devrait être converti en [24, 23, 27] Code:

def uniq_array(col_array):
    x = np.unique(col_array)
    return x
uniq_array_udf = udf(uniq_array,ArrayType(IntegerType()))

Df3 = Df2.withColumn("age_array_unique",uniq_array_udf(Df2.age_array))

Dans le code ci-dessus, Df2.age_array est le tableau sur lequel j'applique l'UDF pour obtenir une colonne différente "age_array_unique" qui ne doit contenir que des valeurs uniques dans le tableau.

Cependant, dès que j'exécute la commande Df3.show(), le message d'erreur suivant s'affiche:

net.razorvine.pickle.PickleException: zéro argument attendu pour la construction de ClassDict (pour numpy.core.multiarray._reconstruct)

Quelqu'un peut-il s'il vous plaît laissez-moi savoir pourquoi cela se produit?

Merci!

21
Preyas

La source du problème est que l'objet renvoyé par la fonction UDF n'est pas conforme au type déclaré. np.unique renvoie non seulement numpy.ndarray, mais convertit également les valeurs numériques en types NumPyincompatibles avec l'API DataFrame. Vous pouvez essayer quelque chose comme ça:

udf(lambda x: list(set(x)), ArrayType(IntegerType()))

ou ceci (pour maintenir l'ordre)

udf(lambda xs: list(OrderedDict((x, None) for x in xs)), 
    ArrayType(IntegerType()))

au lieu.

Si vous voulez vraiment np.unique, vous devez convertir la sortie:

udf(lambda x: np.unique(x).tolist(), ArrayType(IntegerType()))
27
zero323

Vous devez convertir la valeur finale en une liste python. Vous implémentez la fonction comme suit: 

def uniq_array(col_array):
    x = np.unique(col_array)
    return list(x)

En effet, Spark ne comprend pas le format de tableau numpy. Pour alimenter un objet python que Spark DataFrames considère comme un ArrayType, vous devez convertir la sortie en python list avant de la renvoyer.

1
user1632287