2017-09-18 2 views
1

Supposons que j'ai la trame de données de pandas géants suivant, DF1, dans un cahier de jupyter à partir d'un fichier Excel:doublons de marquage dans une colonne séparée à l'aide de pandas géants

Name ID  Password 
A  User_1 PW_1 
A  User_2 PW_2 
A  User_3 PW_3 
B  User_4 PW_4 
B  User_5 PW_5 
C  User_6 PW_6 

Je voudrais ajouter une nouvelle colonne, appelée STAT , qui passe par la colonne Name et pour chaque élément dans Name, si la cellule précédente dans Name contenait le même élément, imprimez dup (pour dupliquer) dans STAT; sinon, ne mettez rien. Dans mon exemple ci-dessus, les utilisateurs 2,3 et 5 doivent avoir dup dans la colonne SRC après mon opération.

Voici ma tentative. J'ajoute une nouvelle colonne vide appelée STAT en utilisant df1.insert, puis je lance:

for index, name in enumerate(df1['Name']): 
    if index > 0: 
     if df1['Name'][index - 1] == name: 
      df1.ix[index, 'STAT'] = 'dup'` 

Cela fonctionne très bien, mais je voudrais savoir

a) si elle peut être améliorée

et plus important

b) Pourquoi lance-t-il un avertissement A value is trying to be set on a copy of a slice from a DataFrame malgré mon utilisation de .ix. Même .loc jette l'avertissement.

Il serait facile de vérifier normalement, mais je l'utilise jupyter portable dans PyCharm, et chaque fois que je recharge le fichier que j'obtenir un _xrsf argument missing from POST.

extrait pertinent de code, appliqué à mon exemple concret. Les noms df différeront:

sort_full = full_set.sort_values(['Name','SRC']) 
dupless_full = sort_full.drop_duplicates(subset = ['Name', 'ER', 'ID', 
'PW'], keep = 'last') 
dupless_full.reset_index(drop = True, inplace = True) 

dupless_full['STAT'] = np.where(dupless_full['Name'] == 
dupless_full['Name'].shift(), 'dup', "") 
+0

Les valeurs de la colonne 'Name' sont-elles triées? – jezrael

+0

Oui. En fait, ils sont triés par une autre colonne, appelée SRC, prenant les valeurs A ou B, après avoir été triés par nom. J'ai choisi de ne pas inclure cette information. –

Répondre

4

Vous pouvez utiliser np.where

df1['Stat'] = np.where(df['Name'] == df['Name'].shift(), 'Dupe', np.nan) 

    Name ID  Password Stat 
0 A  User_1 PW_1  nan 
1 A  User_2 PW_2  Dupe 
2 B  User_3 PW_3  nan 
3 C  User_4 PW_4  nan 
+0

Eh bien, encore une fois, cela fonctionne, et est plus rapide que ma solution, mais il lance toujours le même avertissement. –

+0

Comment avez-vous généré la base de données? Si ce n'est pas généré en utilisant .copy(), cela conduirait à copier l'avertissement. – Vaishali

+0

Je n'utilise pas .copy(), car on m'a dit que ce n'était jamais la bonne façon de générer une trame de données. Est-ce un non-sens? –

0

Si les valeurs dans la colonne Name sont triées est l'utilisation possible duplicated pour masque booléen:

df1['Stat'] = np.where(df1['Name'].duplicated(), 'Dupe', '') 
print (df1) 
    Name  ID Password Stat 
0 A User_1  PW_1  
1 A User_2  PW_2 Dupe 
2 B User_3  PW_3  
3 C User_4  PW_4  

Si les valeurs sont non trié, j'ajoute une comparaison avec un autre answer:

df1['Stat_shift'] = np.where(df1['Name'] == df1['Name'].shift(), 'Dupe', np.nan) 
df1['Stat_duplicated'] = np.where(df1['Name'].duplicated(), 'Dupe', '') 
print (df1) 
    Name  ID Password Stat_shift Stat_duplicated 
0 A User_1  PW_1  nan     
1 A User_2  PW_2  Dupe   Dupe 
2 B User_3  PW_3  nan     
3 A User_2  PW_2  nan   Dupe 
4 C User_4  PW_4  nan     
5 B User_3  PW_3  nan   Dupe 
6 B User_3  PW_3  Dupe   Dupe 
+0

Je pense, OP veut vérifier seulement la valeur précédente, pas tous les doublons dans le cadre. – Zero

+0

C'est possible, mais si les valeurs sont triées, cela devrait également fonctionner. – jezrael

+0

Je voulais dire, seulement si les valeurs sont triées, cela fonctionnera, mais je ne suis pas sûr si OP a déclaré cela n'importe où. – Zero