Je travaille avec un grand ensemble de données (2M + lignes) qui ressemble à ce qui suit:
Id TeamId UserId UniqueId 43 504 722 0 44 504 727 0 45 601 300 1 46 602 722 0 47 602 727 0 48 605 300 1 49 777 300 2 50 777 301 2 51 788 400 3 52 789 400 3 53 100 727 4
Dans ce cas, TeamId 504 et 602 sont les mêmes, 601 correspond à 605 mais pas avec 777 (car il y a une personne de plus dans l'équipe).
Mon objectif est de générer des identifiants uniques pour chaque équipe "unique":
Id TeamId UserId 43 504 722 44 504 727 45 601 300 46 602 722 47 602 727 48 605 300 49 777 300 50 777 301 51 788 400 52 789 400 53 100 727
Une personne peut faire partie d'une équipe de 1, comme dans le cas de UserId 727: il fait partie de l'équipe 504 (avec UserId 722) et de l'équipe 100 (seul). Cela devrait générer 2 identifiants uniques différents pour les deux équipes.
Je ne peux pas groupBy par TeamId uniquement car il détectera TeamId 504 et 602 comme des équipes différentes, ni par UserId car il ne suivra pas équipes.
D'après ce que j'ai compris, cela pourrait être un problème de réseau. J'ai trouvé une requête similaire à celle-ci ici: Regroupez deux valeurs de colonne et créez un identifiant unique
Comment puis-je y parvenir? Toute aide serait appréciée.
3 Réponses :
Pour chaque ligne, créez une nouvelle variable (peut-être un tuple) qui contient les membres de cette équipe.
Id TeamId UserId NewVar 43 504 722 (722, 727) 44 504 727 (722, 727) 45 601 300 (300) 46 602 722 (722, 727) 47 602 727 (722, 727) 48 605 300 (300) 49 777 300 (300, 301) 50 777 301 (300, 301) 51 788 400 (400) 52 789 400 (400) 53 100 727 (727)
après cette étape, comparez la NewVar et attribuez l'id Ps: n'oubliez pas de commander le NewVar
Vous pouvez utiliser pivot_table
pour entrer dans l'index TeamId
et dans les colonnes UserId
, chaque ligne indiquant quels utilisateurs sont dans chaque équipe, comme :
df['UniqueId'] = df.TeamId.map(dfp.sort_values(dfp.columns.tolist()) .diff().abs().any(1).cumsum()) print (df) Id TeamId UserId UniqueId 0 43 504 722 1 1 44 504 727 1 2 45 601 300 3 3 46 602 722 1 4 47 602 727 1 5 48 605 300 3 6 49 777 300 4 7 50 777 301 4 8 51 788 400 2 9 52 789 400 2 10 53 100 727 0
Ensuite, pour pouvoir obtenir le UniqueId, vous pouvez sort_values
par toutes les colonnes, utiliser le diff
entre deux lignes, trouver si tout
par lignes, la signification des différents groupes et cum
tels que:
print (dfp.sort_values(dfp.columns.tolist()).diff().any(1).cumsum()) TeamId 100 0 504 1 #same number for 504 and 602 but not 100 as you want 602 1 788 2 789 2 601 3 605 3 777 4 dtype: int64
afin d'obtenir la nouvelle colonne, vous peut utiliser map
:
dfp = df.pivot_table( values='Id', index='TeamId', columns='UserId', aggfunc=np.any, fill_value=False) print (dfp) UserId 300 301 400 722 727 TeamId 100 False False False False True 504 False False False True True 601 True False False False False 602 False False False True True 605 True False False False False 777 True True False False False 788 False False True False False 789 False False True False False
Utilisez 2 groupby pour obtenir le résultat:
UserId TeamId 0 (300,) (601, 605) 1 (300, 301) (777,) 2 (400,) (788, 789) 3 (722, 727) (504, 602) 4 (727,) (100,)
résultat:
import pandas as pd df = pd.DataFrame( {'Id' :[43,44,45,46,47,48,49,50,51,52,53], 'TeamId':[504,504,601,602,602,605,777,777,788,789,100], 'UserId':[722,727,300,722,727,300,300,301,400,400,727]}) df_grouped = df.groupby('TeamId')['UserId'].apply(tuple).to_frame().reset_index() df_grouped = df_grouped.groupby('UserId')['TeamId'].apply(tuple).to_frame().reset_index() print(df_grouped)
itérez simplement la colonne TeamId pour définir le numéro d'équipe. ..
donc l'équipe a 2 membres chacun?