Bien que je sois capable de créer des tableaux croisés dynamiques dans Excel, j'aimerais utiliser Python pour finalement combiner des lignes avec des champs similaires. Dans ce cas, la ligne doit être combinée avec les mêmes "id" et "location" uniquement.
Entrée:
id location1 location2 date code1 code2 111 Park Beach 1/1/2018 7765 7534 143 School 2/5/2018 3345 223 Library 3/5/2018 3345
Sortie 1:
id location date code 111 Park, Beach 1/1/2018 7765, 7534 143 School 2/5/2018 3345 223 Library 3/5/2018 3345
Sortie 2:
id location date code 111 Park 1/1/2018 7765 143 School 2/5/2018 3345 111 Beach 1/1/2018 7534 223 Library 3/5/2018 3345
La seule raison pour laquelle je voudrais comprendre les requêtes pour les deux sorties est parce que j'ai plusieurs autres colonnes avec des définitions pour ces codes. Je sais que je devrais utiliser l'ID et l'emplacement groupby, cependant, j'ai des difficultés avec la fusion dans la sortie 1 et avec la sortie 2 avec la création des nouvelles lignes.
4 Réponses :
IIUC,
mapper = lambda x : ",".join(x) df["code"] = df["code"].astype(str) df.groupby("id").agg({"location" : mapper, "code" : mapper}) location code id 111 Park,Beach 7765,7534 143 School 3345 223 Library 3345
Essayez ceci:
df['date'] = pd.to_datetime(df['date']) df['code'] = df['code'].astype(str) df = df.groupby(by=['id', 'date'], as_index=False).agg({'location': ','.join, 'code': ','.join}) print(df) id date location code 0 111 2018-01-01 Park,Beach 7765,7534 1 143 2018-02-05 School 3345 2 223 2018-03-05 Library 3345
Vous pouvez essayer ceci:
Rejoignez les colonnes nécessaires dans dataframe
output2 = output1["location"].str.split(pat=",",expand=True) output2.columns = ["location_"+ str(i) for i in output2.columns] output3 = output1["code"].str.split(pat=",",expand=True) output3.columns = ["code"+ str(i) for i in output3.columns] final_output = pd.concat([output1, output2, output3],axis=1) final_output = final_output.fillna('')
Dans cette approche, si la personne A va à l'école deux fois le même jour, la sortie prendra des valeurs uniques comme école
au lieu d'afficher école, école
. En même temps, disons que la personne A va à l'école deux fois le même jour mais a deux codes différents, puis elle produit les deux School,School
df["code"] = df["code"].astype(str) output1 = df.groupby(["id","date"]).agg({"location": list,"code":list}).reset_index() ## check location and code having same set of unique values, will be performing `set` operation take unique elements unique_values = output1[output1["location"].apply(set).apply(len) == output1["code"].apply(set).apply(len)] ## check location and code having different set of unique values, this case, might have same location with two different dates, ## no need to take `set` operation for this other_values = output1[output1["location"].apply(set).apply(len) != output1["code"].apply(set).apply(len)] ## convert to set to , separated unique_values["location"] = unique_values["location"].apply(set).apply(",".join) unique_values["code"] = unique_values["code"].apply(set).apply(",".join) other_values["location"] = other_values["location"].apply(",".join) other_values["code"] = other_values["code"].apply(",".join) ## join both the dataframe output1 = pd.concat([unique_values, other_values]).sort_index()
cela produit output1
dataframe
Le code ci-dessous sert à agrandir l'emplacement
et la colonne code
dans dataframe,
df["code"] = df["code"].astype(str) output1 = df.groupby("id").agg({"location": ",".join,"code":",".join,"date":'first'}).reset_index()
Le résultat final est
Une question, comment adapteriez-vous le code pour éviter que le même emplacement ne soit répété deux fois? Par exemple, si la personne A se rend à l'école deux fois le même jour, la sortie affiche École, École
. Je voudrais que cela apparaisse comme École
uniquement dans ce cas. Cependant, disons que la personne A va à l'école deux fois le même jour mais a deux codes
différents. Ensuite, la sortie devrait être École, École. Merci d'avance!
De plus, je remarque des doublons dans le sens où la personne A se rend au Parc, École
ou École, Parc
Y a-t-il un ordre par opération que je devrais utiliser pour m'assurer que ne se produit pas?
@Logan, j'ai mis à jour la solution. Pour supprimer les doublons, vous devrez peut-être effectuer drop_duplicates
. Mais, j'ai géré la situation où la personne va à l ' école
deux fois le même jour avec des codes différents.
Pour CASE 1, DataFrame.groupby
sur id et date
puis agréger la colonne location et code
à l'aide de .join
: XXX
Pour CASE 2, utilisez DataFrame.melt
, puis utilisez DataFrame.groupby
sur id et variable
et utilisez une transformation en utilisant cumcount
pour ajouter un compteur séquentiel à la colonne variable
, enfin utiliser .set_index
, unstack
, droplevel
.
# CASE 1: print(df1) id date location code 0 111 1/1/2018 Park, Beach 7765, 7534 1 143 2/5/2018 School 3345 2 223 3/5/2018 Library 3345 # CASE 2: print(df2) variable id date code1 code2 location1 location2 0 111 1/1/2018 7765 7534 Park Beach 1 143 2/5/2018 3345 NaN School NaN 2 223 3/5/2018 3345 NaN Library NaN
Résultat:
df2 = df.melt(id_vars=['id', 'date']) df2['variable'] += df2.groupby(['id', 'variable']).cumcount().add(1).astype(str) df2 = df2.set_index(['id', 'date', 'variable']).unstack().droplevel(0, 1).reset_index()
S'agit-il d'un dataframe pandas? vous souhaitez également combiner par
id
etdate
, n'est-ce pas?Correct, pandas df. Et je ne voudrais combiner que si
id
etdate
sont les mêmes.