1
votes

Supprimer les doublons de la liste des cadres de données python

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)


0 commentaires

6 Réponses :


3
votes

Utilisez set pour supprimer les doublons.

Vous n'avez pas non plus besoin de la boucle for

  df["newlist"] = list(set( df["text_lemmatized"] ))


3 commentaires

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"



0
votes
df.drop_duplicates(subset ="text_lemmatized", 
                     keep = First, inplace = True) 
keep = First, means keep the first occurrence  

1 commentaires

Cela ne fonctionne pas et me donne la même erreur: "ValueError: Length of values ​​does not match length of index" ...



1
votes

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


2 commentaires

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)



0
votes

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]


8 commentaires

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)))



0
votes

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)

`

my final df


1 commentaires

Cela ne semble pas fonctionner et me donne la même erreur qu'avant où il divise chaque mot en alphabets



0
votes

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


0 commentaires