2017-09-25 1 views
0

J'ai une dataframe df avec quelques colonnes. J'essaie de faire quelque chose et je reçois une erreur étrange au lieu d'un résultat que j'attends.Erreur de clé lors de l'application de la fonction lambda sur Pyspark

Mon idée est de générer une valeur numérique pour chaque valeur distincte de la colonne de trame de données, et d'ajouter la paire "real_value" : "numeric_value" à un dictionnaire.

Le dictionnaire global où enregistrer les résultats est la suivante:

dict_res = {} 

J'ai la fonction suivante qui passe une valeur et le nom d'attribut, obtient le dictionnaire selon le atr du dictionnaire global « dict_res » et si la valeur existe en tant que clé dans le dictionnaire, renvoie sa valeur numérique et, si ce n'est pas le cas, génère une nouvelle valeur numérique définie comme float(len(dict_res[atr]) + 1).

def indexMethod(value, atr): 
    global dict_res 
    res = float(len(dict_res[atr]) + 1) 
    if value in dict_res[atr]: 
     res = dict_res[atr][value] 
    else: 
     dict_res[atr][value] = res 
    return res 

itérées suivant fragment de code sur les attributs que je veux générer une valeur numérique à partir, et si un dictionnaire équivalent à l'attribut n'est pas créé dans le dictionnaire global « dict_res » il est créé, puis applique avec une fonction lambda la méthode spécifiée ci-dessus.

for column in columns_to_index: 
    udf_func = UserDefinedFunction(lambda value: indexMethod(value, column), DoubleType()) 
    if(not column in dict_res): 
     dict_res[column] = {} 
    col2 = udf_func(df[column]) 
    df = df.withColumn('newCol', col2) 
    .... 

donc ce que je pense est de générer le dictionnaire avec les équivalences, ainsi qu'une nouvelle colonne avec les mêmes que dans le équivalences dictionnaire.

Après le processus, j'imprimer le dict comme suit:

print(dict_res) 

Et le résultat que je reçois est la suivante:

{'ATR1': {}, 'ATR2': {}, ...} 

Ainsi, les dictionnaires sont vides. Mais l'erreur la plus importante est que lorsque je tente de montrer la dataframe « df » j'obtenir l'erreur suivante:

KeyError: 'ATR1' 

Comment est-ce possible si j'ai un dictionnaire avec cette clé?

espérons que vous pouvez me aider ...

Répondre

0

Je ne pense pas que vous pouvez mettre à jour un objet python extérieur (global ou non) par un UDF qui ne fonctionne que sur les actions lignes.

Une autre façon de résoudre le problème est d'utiliser distinct():

dict_res = dict() 
for column in columns_to_index: 
    dict_res[column] = df.select(column).distinct().toPandas().to_dict() 
+0

Il est utile quand j'ai un dataframe et il ne sera pas escaled plus. Mais si plus tard j'ai de nouvelles données que je veux traiter aussi, et je veux combiner les résultats avec ceux déjà obtenus dans le dictionnaire 'dict_res'? Merci pour la réponse, de toute façon! – jartymcfly

+0

Vous pouvez utiliser 'subtract', puis' distinct' et ajouter les nouvelles données aux dictionnaires existants. – MaFF