J'ai une trame de données df
df = pd.DataFrame(np.arange(20).reshape(10, -1),
[['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'd'],
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']],
['X', 'Y'])
Comment obtenir les première et dernière lignes, groupées par le premier niveau de l'index?
J'ai essayé
df.groupby(level=0).agg(['first', 'last']).stack()
et j'ai
X Y
a first 0 1
last 6 7
b first 8 9
last 12 13
c first 14 15
last 16 17
d first 18 19
last 18 19
C'est tellement proche de ce que je veux. Comment puis-je conserver l'index de niveau 1 et l'obtenir à la place:
X Y
a a 0 1
d 6 7
b e 8 9
g 12 13
c h 14 15
i 16 17
d j 18 19
j 18 19
def first_last(df):
return df.ix[[0, -1]]
df.groupby(level=0, group_keys=False).apply(first_last)
idx = df.index.to_series().groupby(level=0).agg(['first', 'last']).stack()
df.loc[idx]
J'ai également abusé de la fonction agg
. Le code ci-dessous fonctionne, mais est beaucoup plus laid.
df.reset_index(1).groupby(level=0).agg(['first', 'last']).stack() \
.set_index('level_1', append=True).reset_index(1, drop=True) \
.rename_axis([None, None])
per @unutbu: agg(['first', 'last'])
prend les premières valeurs non na.
J'ai interprété cela comme, il doit alors être nécessaire d'exécuter cette colonne par colonne. En outre, forcer le niveau d'index = 1 à s'aligner peut même ne pas avoir de sens.
Incluons un autre test
df = pd.DataFrame(np.arange(20).reshape(10, -1),
[list('aaaabbbccd'),
list('abcdefghij')],
list('XY'))
df.loc[Tuple('aa'), 'X'] = np.nan
def first_last(df):
return df.ix[[0, -1]]
df.groupby(level=0, group_keys=False).apply(first_last)
df.reset_index(1).groupby(level=0).agg(['first', 'last']).stack() \
.set_index('level_1', append=True).reset_index(1, drop=True) \
.rename_axis([None, None])
Assez sur! Cette deuxième solution prend la première valeur valide dans la colonne X. Il est désormais absurde d'avoir forcé cette valeur à s'aligner sur l'index a.
Cela pourrait être une solution facile.
df.groupby(level = 0, as_index= False).nth([0,-1])
X Y
a a 0 1
d 6 7
b e 8 9
g 12 13
c h 14 15
i 16 17
d j 18 19
J'espère que cela t'aides. (Y)
Veuillez essayer ceci:
Pour la dernière valeur: df.groupby('Column_name').nth(-1)
,
Pour la première valeur: df.groupby('Column_name').nth(0)