web-dev-qa-db-fra.com

Comment arrondir la colonne datetime au quart d'heure le plus proche

J'ai chargé un fichier de données dans un Python pandas dataframe. J'ai une colonne datetime du format 2015-07-18 13:53:33.280.

Ce que je dois faire, c'est créer une nouvelle colonne qui arrondit cela au quart d'heure le plus proche. Ainsi, la date ci-dessus sera arrondie à 2015-07-18 13:45:00.000.

Comment puis-je faire cela chez les pandas? J'ai essayé d'utiliser la solution de ici , mais j'obtiens un 'Series' object has no attribute 'year' Erreur.

31
sfactor

En supposant que votre série est composée d'objets datetime, vous devez utiliser Series.apply. Exemple -

import datetime
df['<column>'] = df['<column>'].apply(lambda dt: datetime.datetime(dt.year, dt.month, dt.day, dt.hour,15*(dt.minute // 15)))

L'exemple ci-dessus pour toujours arrondir au quart d'heure précédent (comportement similaire à la fonction de plancher).

MODIFIER

Pour arrondir au quart d'heure correct (comme dans, si ses 7 minutes 30 secondes après le trimestre précédent, pour afficher le trimestre suivant). Nous pouvons utiliser l'exemple ci-dessous -

import datetime
df['<column>'] = df['<column>'].apply(lambda dt: datetime.datetime(dt.year, dt.month, dt.day, dt.hour,15*round((float(dt.minute) + float(dt.second)/60) / 15)))

Ce qui précède ne prendrait en compte que les dernières secondes, si vous voulez que la milliseconde/microseconde soit prise en compte, vous pouvez l'ajouter à l'équation ci-dessus comme - (float(dt.minute) + float(dt.second)/60 + float(dt.microsecond)/60000000)

33
Anand S Kumar

Vous pouvez utiliser round(freq) . Il existe également un raccourci column.dt pour l'accès aux fonctions datetime (comme le suggère @ laurens-koppenol).

Voici une ligne:

df['old column'].dt.round('15min')  

Des alias de chaîne pour les fréquences valides peuvent être trouvés ici . Exemple de travail complet:

In [1]: import pandas as pd    
In [2]: df = pd.DataFrame([pd.Timestamp('2015-07-18 13:53:33.280'),
                           pd.Timestamp('2015-07-18 13:33:33.330')],
                         columns=['old column'])

In [3]: df['new column']=df['old column'].dt.round('15min')  
In [4]: df
Out[4]: 
               old column          new column
0 2015-07-18 13:53:33.280 2015-07-18 14:00:00
1 2015-07-18 13:33:33.330 2015-07-18 13:30:00
81
tworec

Ça a l'air un peu plus joli

column.dt. autorise les fonctions datetime pour les colonnes datetime, comme column.str. fait pour les colonnes de type chaîne

référence de l'API des propriétés de type datetime

import pandas as pd

# test df
df = pd.DataFrame([{'old_column':pd.Timestamp('2015-07-18 13:53:33.280')}])

df['new_column'] = df['old_column'].dt.round('15min')

df
12
Laurens Koppenol

La réponse d'Anand S Kumar ne s'arrondit pas au quart d'heure le plus proche, elle coupe les minutes aux 15 minutes les plus proches en dessous.

En fait, dans votre exemple 2015-07-18 13:53:33.280 devrait arrondir à 2015-07-18 14:00:00.000 puisque 53:33.280 est plus proche de 60 minutes que 45 minutes.

J'ai trouvé une réponse plus robuste pour arrondir ce post .

Pour votre situation, cela devrait fonctionner:

import datetime

def round_time(time, round_to):
    """roundTo is the number of minutes to round to"""
    rounded = time + datetime.timedelta(minutes=round_to/2.)
    rounded -= datetime.timedelta(minutes=rounded.minute % round_to,
                                  seconds=rounded.second,
                                  microseconds=rounded.microsecond)
    return rounded

dt['dtcolumn'] = df['dtcolumn'].apply(lambda x: round_time(x))
6
Eric Blum