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?