4 votes

Multi-indexation - accéder à la dernière fois dans chaque jour

Nouveau pour la multi-indexation dans Pandas. J'ai des données qui ressemblent à ceci

Date        Time      value
2014-01-14  12:00:04   .424
            12:01:12   .342
            12:01:19   .341
            ...
            12:05:49   .23
2014-05-12  ...
            1:02:42    .23
....

Pour l'instant, je veux accéder à la dernière heure pour chaque date et stocker la valeur dans un tableau. J'ai créé un multi-index comme ceci

df= pd.read_csv("df.csv",index_col=0)
df.index = pd.to_datetime(df.index,infer_datetime_format=True)
df.index =        pd.MultiIndex.from_arrays([df.index.date,df.index.time],names=['Date','Time'])

df= df[~df.index.duplicated(keep='first')]
dates = df.index.get_level_values(0)

J'ai donc des dates enregistrées sous forme de tableau. Je veux itérer à travers les dates mais je n'arrive pas à trouver la bonne syntaxe ou j'accède aux valeurs de manière incorrecte. J'ai essayé une boucle for mais je n'arrive pas à la faire fonctionner ( for date in dates ) et ne peut pas non plus faire d'accès direct ( df.loc[dates[i]] ou quelque chose comme ça). De plus, le nombre de variables temporelles dans chaque date varie. Existe-t-il un moyen de résoudre ce problème ?

3voto

unutbu Points 222216

Cela ressemble à un groupby/max opération. Plus précisément, vous voulez regrouper par le Date et de regrouper les Time en prenant les max . Puisque l'agrégation ne peut se faire que sur colonne nous devrons modifier les valeurs Time niveau d'index dans une colonne (en utilisant reset_index ):

import pandas as pd

df = pd.DataFrame({'Date': ['2014-01-14', '2014-01-14', '2014-01-14', '2014-01-14', '2014-05-12', '2014-05-12'], 'Time': ['12:00:04', '12:01:12', '12:01:19', '12:05:49', '01:01:59', '01:02:42'], 'value': [0.42399999999999999, 0.34200000000000003, 0.34100000000000003, 0.23000000000000001, 0.0, 0.23000000000000001]})
df['Date'] = pd.to_datetime(df['Date'])
df = df.set_index(['Date', 'Time'])

df = df.reset_index('Time', drop=False)
max_times = df.groupby(level=0)['Time'].max()
print(max_times)

donne

Date
2014-01-14    12:05:49
2014-05-12     1:02:42
Name: Time, dtype: object

Si vous le souhaitez pour sélectionner la ligne entière alors vous pouvez utiliser idxmax -- mais il y a une mise en garde. idxmax renvoie les étiquettes d'index. Par conséquent, l'index doit être unique pour les étiquettes afin de signifier les rangées uniques. Puisque les Date n'est pas en soi unique, pour utiliser idxmax nous devrons reset_index complètement (pour faire un index d'entiers uniques) :

df = pd.DataFrame({'Date': ['2014-01-14', '2014-01-14', '2014-01-14', '2014-01-14', '2014-05-12', '2014-05-12'], 'Time': ['12:00:04', '12:01:12', '12:01:19', '12:05:49', '01:01:59', '1:02:42'], 'value': [0.42399999999999999, 0.34200000000000003, 0.34100000000000003, 0.23000000000000001, 0.0, 0.23000000000000001]})
df['Date'] = pd.to_datetime(df['Date'])
df['Time'] = pd.to_timedelta(df['Time'])
df = df.set_index(['Date', 'Time'])

df = df.reset_index()
idx = df.groupby(['Date'])['Time'].idxmax()
print(df.loc[idx])

donne

        Date     Time  value
3 2014-01-14 12:05:49   0.23
5 2014-05-12 01:02:42   0.23

Je ne vois pas de bon moyen de le faire tout en conservant le MultiIndex. Il est plus facile d'effectuer le groupby avant de régler le MultiIndex. De plus, il est probablement préférable de conserver les dates comme une seule valeur au lieu de le diviser en deux parties. Notez qu'étant donné une série de type date-heure/période, l'élément .dt accesseur vous permet d'accéder facilement à la date et le time au besoin. Ainsi, vous pouvez regrouper par le Date sans faire un Date colonne :

df = pd.DataFrame({'DateTime': ['2014-01-14 12:00:04', '2014-01-14 12:01:12', '2014-01-14 12:01:19', '2014-01-14 12:05:49', '2014-05-12 01:01:59', '2014-05-12 01:02:42'], 'value': [0.42399999999999999, 0.34200000000000003, 0.34100000000000003, 0.23000000000000001, 0.0, 0.23000000000000001]})
df['DateTime'] = pd.to_datetime(df['DateTime'])
# df = pd.read_csv('df.csv', parse_dates=[0])

idx = df.groupby(df['DateTime'].dt.date)['DateTime'].idxmax()
result = df.loc[idx]
print(result)

donne

             DateTime  value
3 2014-01-14 12:05:49   0.23
5 2014-05-12 01:02:42   0.23

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X