J'ai un pandas df où chaque ligne est une liste de mots. La liste contient des mots en double. Je veux supprimer les mots en double.
J'ai essayé d'utiliser dict.fromkeys (listname) dans une boucle for pour parcourir chaque ligne du df. Mais cela divise les mots en alphabets
['clear', 'pending', 'order', 'pending', 'order'] ... [[, ', c, l, e, a, r, ,, , p, n, d, i, g, o, ]] ['pending', 'activation', 'clear', 'pending', ... ... [[, ', p, e, n, d, i, g, ,, , a, c, t, v, o, ...
Le résultat attendu est ==>
['clear', 'pending', 'order', 'pending', 'order'] ['clear', 'pending', 'order'] ['pending', 'activation', 'clear', 'pending'] ['pending', 'activation', 'clear']
Le résultat réel est
filepath = "C:/abc5/Python/Clustering/output2.csv"
df = pd.read_csv(filepath,encoding='windows-1252')
df["newlist"] = df["text_lemmatized"]
for i in range(0,len(df)):
l = df["text_lemmatized"][i]
df["newlist"][i] = list(dict.fromkeys(l))
print(df)
6 Réponses :
Utilisez set pour supprimer les doublons.
Vous n'avez pas non plus besoin de la boucle for
df["newlist"] = list(set( df["text_lemmatized"] ))
J'obtiens l'erreur ... ValueError: La longueur des valeurs ne correspond pas à la longueur de l'index
Quelle erreur? Vous devez fournir au moins le message d'erreur
L'erreur que j'obtiens est "ValueError: La longueur des valeurs ne correspond pas à la longueur de l'index"
df.drop_duplicates(subset ="text_lemmatized",
keep = First, inplace = True)
keep = First, means keep the first occurrence
Cela ne fonctionne pas et me donne la même erreur: "ValueError: Length of values does not match length of index" ...
Utilisez simplement series.map et np.unique
Vos exemples de données:
df.text_lemmatized.map(pd.unique) Out[51]: 0 [clear, pending, order] 1 [pending, activation, clear] Name: text_lemmatized, dtype: object
Si vous préférez qu'il ne soit pas trié, utilisez pd.unique
Out[43]:
text_lemmatized
0 [clear, pending, order, pending, order]
1 [pending, activation, clear, pending]
df.text_lemmatized.map(np.unique)
Out[44]:
0 [clear, order, pending]
1 [activation, clear, pending]
Name: val, dtype: object
Il n'y a pas d'erreur mais cela ne supprime pas les doublons. Ne marche pas.
@AnoopMahajan: c'est bizarre! cela fonctionne sur mon système avec votre échantillon. L'avez-vous réattribué comme df ['newlist'] = df.text_lemmatized.map (pd.unique)
Le problème est qu'il n'y a pas de listes, mais des chaînes, il est donc nécessaire de convertir chaque valeur en liste par ast.literal_eval , puis il est possible de convertir les valeurs en set s pour supprimer doublons:
df['newlist'] = df['text_lemmatized'].map(lambda x: list(set(x)))
Ou utilisez dict.fromkeys:
df['text_lemmatized'] = df['text_lemmatized'].map(ast.literal_eval) df['newlist'] = df['text_lemmatized'].map(lambda x: list(set(x)))
Une autre idée est de convertir la colonne text_lemmatized aux listes en une étape puis supprimer les doublons dans une autre étape, l'avantage est les listes dans la colonne text_lemmatized pour le traitement suivant:
f = lambda x: list(dict.fromkeys(ast.literal_eval(x))) df['newlist'] = df['text_lemmatized'].map(f)
EDIT :
Après quelques discussions, la solution est:
import ast
df['newlist'] = df['text_lemmatized'].map(lambda x: list(set(ast.literal_eval(x))))
print(df)
text_lemmatized newlist
0 [clear, pending, order, pending, order] [clear, pending, order]
1 [pending, activation, clear, pending] [clear, activation, pending]
Je suis désolé jezrael ... Quand j'ai incorporé ceci dans mon code complet, il me donne maintenant une erreur comme "ValueError: nœud ou chaîne malformé: ['clear', 'pending', 'order', 'pending', ' ordre']
@AnoopMahajan - Comment fonctionne la dernière solution avec le changement df ['text_lemmatized'] = df ['text_lemmatized']. Map (ast.literal_eval) à df ['text_lemmatized'] = df [' text_lemmatized ']. str.strip ("[]"). str.split (', ') ?
essayé ce qui suit, df ["newlist"] = df ["text_lemmatized"] df ['text_lemmatized'] = df ['text_lemmatized']. str.strip ("[]"). str.split (',') df ['newlist'] = df ['text_lemmatized']. map (lambda x: list (set (x))) ... J'obtiens une erreur comme "AttributeError: Ne peut utiliser l'accesseur .str avec des valeurs de chaîne, qui utilisent np .object_ dtype dans les pandas "
@AnoopMahajan - Qu'est-ce que print (type (df ['text_lemmatized']. Iat [0])) ?
print renvoie
Il suffit donc de df ['newlist'] = df ['text_lemmatized']. Map (lambda x: list (set (x)))
comment appliquer la même fonction dans plusieurs colonnes
@dondapati - Utilisez applymap comme df [['newlist', 'col1', 'col2']] = df [['newlist', 'col1', 'col2']]. applymap (lambda x: liste (set (x)))
Votre code de suppression des doublons semble correct. J'ai essayé de suivre et cela a bien fonctionné. Je suppose que le problème vient de la façon dont vous ajoutez la liste dans la colonne dataframe.
df["newlist"] = list_with_unique_words df
sortie [['effacer', 'en attente', 'commande'], ['en attente', 'activation', 'effacer']]
`list_from_df = [['clear', 'pending', 'order', 'pending', 'order'],
['pending', 'activation', 'clear', 'pending']]
list_with_unique_words = []
for x in list_from_df:
unique_words = list(dict.fromkeys(x))
list_with_unique_words.append(unique_words)
print(list_with_unique_words)
`
Cela ne semble pas fonctionner et me donne la même erreur qu'avant où il divise chaque mot en alphabets
La solution est ==>
import pandas as pd filepath = "C:/abc5/Python/Clustering/output2.csv" df = pd.read_csv(filepath,encoding='windows-1252') df["newlist"] = df["text_lemmatized"] df['newlist'] = df['text_lemmatized'].map(lambda x: list(set(x))) print(df)
Merci à jezrael et à tous les autres qui ont aidé à se limiter à cette solution