Voici un exemple rapide du problème:

J'ai le dataframe suivant:

data = {'name': ["name_1", "name_2" , "name_3" , "name_2" , "name_1" , "name_2" , "name_2" ], 'col_B': ["a", "a" , "a" , "b" , "a" , "c" , "a" ] , 'col_C' : [1 , 1 , 1 , 1 , 5 , 6 , 1]}
df = pd.DataFrame(data=data)

df # Would give the following df below :
     name col_B  col_C
0  name_1     a      1
1  name_2     a      1
2  name_3     a      1
3  name_2     b      1
4  name_1     a      5
5  name_2     c      6
6  name_2     a      1

Ce dont j'ai besoin est de vérifier le nom de la combinaison + col_B et pour les doublons, col_C -> 0. Par exemple:

     name col_B  col_C
0  name_1     a      1
1  name_2     a      1
2  name_3     a      1
3  name_2     b      1
4  name_1     a      0
5  name_2     c      6
6  name_2     a      0

Pour cela, j'ai créé ce qui suit:

list_tst = []

for index, row in df.iterrows():

   if (row['name']+row['col_B'] in list_tst): 
      row['col_C'] = 0  # If already in the list set value to zero ( it's a duplicate )
   list_tst.append(row['name']+row['col_B']) # if not unique then add to list, could be inside 'else'

Mais comme prévu, cela prend trop de temps à s'exécuter avec des millions de lignes. Quelqu'un pourrait-il suggérer d'utiliser la vectorisation pour cela?

Merci!

Code complet:

import pandas as pd


data = {'name': ["name_1", "name_2" , "name_3" , "name_2" , "name_1" , "name_2" , "name_2" ], 'col_B': ["a", "a" , "a" , "b" , "a" , "c" , "a" ] , 'col_C' : [1 , 1 , 1 , 1 , 5 , 6 , 1]}
df = pd.DataFrame(data=data)

list_tst = []

for index, row in df.iterrows():

   if (row['name']+row['col_B'] in list_tst):
      row['col_C'] = 0
   list_tst.append(row['name']+row['col_B'])
2
spYder 13 avril 2020 à 18:58

2 réponses

Meilleure réponse

Est-ce mask sur duplicated:

df['col_C'].mask(df.duplicated(['name','col_B']),0)

Production:

0    1
1    1
2    1
3    1
4    0
5    6
6    0
Name: col_C, dtype: int64
2
Quang Hoang 13 avril 2020 à 16:00

Devrait être rapide cumcount avec groupby

df.col_C*=df.groupby(['name','col_B']).cumcount().eq(0)
df
     name col_B  col_C
0  name_1     a      1
1  name_2     a      1
2  name_3     a      1
3  name_2     b      1
4  name_1     a      0
5  name_2     c      6
6  name_2     a      0
1
BENY 13 avril 2020 à 16:11