J'ai un dataframe df comme:
GROUP TYPE COUNT A 1 5 A 2 10 A .5 B 1 3 B 2 9 B .33 C 1 20 C 2 100 C .2
Je voudrais ajouter une ligne pour chaque groupe afin que la nouvelle ligne calcule le quotient de COUNT où TYPE vaut 2 et COUNT où TYPE vaut 1 pour chaque GROUP ala: p>
GROUP TYPE COUNT A 1 5 A 2 10 B 1 3 B 2 9 C 1 20 C 2 100
Merci d'avance.
4 Réponses :
Vous pouvez faire:
GROUP TYPE COUNT
GROUP
A 0 A 1.0 5.000000
1 A 2.0 10.000000
1 A NaN 0.500000
B 2 B 1.0 3.000000
3 B 2.0 9.000000
3 B NaN 0.333333
C 4 C 1.0 20.000000
5 C 2.0 100.000000
5 C NaN 0.200000
Sortie
import numpy as np
import pandas as pd
def add_quotient(x):
last_row = x.iloc[-1]
last_row['COUNT'] = x[x.TYPE == 1].COUNT.min() / x[x.TYPE == 2].COUNT.max()
last_row['TYPE'] = np.nan
return x.append(last_row)
print(df.groupby('GROUP').apply(add_quotient))
Notez que la fonction sélectionne le min du TYPE == 1 et le maximum du TYPE == 2 , au cas où il y aurait plus d'une valeur par groupe. Et le TYPE est défini sur np.nan , mais cela peut être facilement modifié.
GROUP TYPE value 0 A 1 5.000000 3 A 2 10.000000 6 A div 0.500000 1 B 1 3.000000 4 B 2 9.000000 7 B div 0.333333 2 C 1 20.000000 5 C 2 100.000000 8 C div 0.200000
s=df[df.TYPE.isin([1,2])].sort_values(['GROUP','TYPE']).groupby('GROUP').COUNT.apply(lambda x : x.iloc[0]/x.iloc[1])
# I am sort and filter your original df ,to make they are ordered and only have type 1 and 2
pd.concat([df,s.reset_index()]).sort_values('GROUP')
# cancat your result back
Out[77]:
COUNT GROUP TYPE
0 5.000000 A 1.0
1 10.000000 A 2.0
0 0.500000 A NaN
2 3.000000 B 1.0
3 9.000000 B 2.0
1 0.333333 B NaN
4 20.000000 C 1.0
5 100.000000 C 2.0
2 0.200000 C NaN
Voici un moyen d'utiliser d'abord sort_values 'par' ['GROUP', 'TYPE'] afin de s'assurer que TYPE 2 vient avant 1 puis GroupBy GROUP .
Ensuite, utilisez first et last pour calculer la fusion quocient et externe avec df:
g = df.sort_values(['GROUP', 'TYPE']).groupby('GROUP')
s = (g.first()/ g.nth(1)).COUNT.reset_index()
df.merge(s, on = ['GROUP','COUNT'], how='outer').fillna(' ').sort_values('GROUP')
GROUP TYPE COUNT
0 A 1 5.000000
1 A 2 10.000000
6 A 0.500000
2 B 1 3.000000
3 B 2 9.000000
7 B 0.333333
4 C 1 20.000000
5 C 2 100.000000
8 C 0.200000
Cela ne fonctionnera que s'il n'y a que deux types, ce que le demandeur dit dans les commentaires ne sera pas toujours le cas.
Qu'en est-il du type 0 . En général, j'éviterais le positionnement relatif
Chaque groupe a-t-il toujours exactement 2 entrées, une pour chaque type?
parfois un groupe a plus de deux
typesmais je veux seulement divisertype2 partype1D'accord, et il n'y a jamais qu'une seule ligne pour chaque type dans chaque groupe?