2017-10-20 54 views
0

J'ai une colonne d'un Pandas DataFrame qui est le jour de l'année fractionnaire (DOY). Cette colonne apparaît comme:Conversion d'une fraction de jour de l'année en Pandas Datetime

   DOY 
0  200.749967 
1  200.791667 
2  200.833367 
3  200.874967 
4  200.916667 
5  200.958367 
6  200.999967 
7  201.041667 
     ...  
3491 627.166667 
3492 627.333367 
3493 627.499967 
3494 627.666667 
3495 627.833367 
3496 627.999967 
3497 628.166667 
3498 628.333367 
Name: DOY, Length: 3499, dtype: float64 

L'année de départ est 2011, mais les données de DOY se poursuit avec des valeurs croissantes jusqu'en 2012 sans remise à zéro de la nouvelle année. Comment puis-je le convertir en format Pandas DatetimeIndex avec le format 'AAAA-MM-JJ HH: MM: SS'?

Répondre

2

Une façon que je peux penser à faire est de convertir votre colonne en TimeDelta, puis l'ajouter au décalage de base (2011/1/1).

df.DOY = pd.to_datetime('2011-1-1') + pd.to_timedelta(df.DOY, unit='D') 
print(df.DOY) 
0  2011-07-20 17:59:57.148800 
1  2011-07-20 19:00:00.028800 
2  2011-07-20 20:00:02.908800 
3  2011-07-20 20:59:57.148800 
4  2011-07-20 22:00:00.028800 
5  2011-07-20 23:00:02.908800 
6  2011-07-20 23:59:57.148800 
7  2011-07-21 01:00:00.028800 
     ... 
3491 2012-09-19 04:00:00.028800 
3492 2012-09-19 08:00:02.908800 
3493 2012-09-19 11:59:57.148800 
3494 2012-09-19 16:00:00.028800 
3495 2012-09-19 20:00:02.908800 
3496 2012-09-19 23:59:57.148800 
3497 2012-09-20 04:00:00.028800 
3498 2012-09-20 08:00:02.908800 
Name: DOY, dtype: datetime64[ns] 

Une autre méthode serait d'appeler pd.to_datetime avec le jeu de paramètres origin, comme le montre agtoever dans their answer.

+0

Pourquoi ne pas utiliser le paramètre '' origin' dans to_datetime'? – agtoever

+0

@agtoever Nice, je ne savais pas que tu pouvais. (mise à jour de votre réponse) –

+0

Voir la réponse supplémentaire J'ai ajouté concernant le décalage de 1 jour nécessaire pour donner des résultats Datetime corrects. – PJW

2

Il suffit d'utiliser to_datetime avec les paramètres appropiate (read the manual):

>>> pandas.to_datetime([0,0.1,200,400,800], unit='D', origin=pandas.Timestamp('01-01-2011')) 

DatetimeIndex(['2011-01-01 00:00:00', '2011-01-01 02:24:00', '2011-07-20 00:00:00', '2012-02-05 00:00:00', '2013-03-11 00:00:00'], dtype='datetime64[ns]', freq=None) 
+0

Merci c'est évidemment une réponse équivalente et très bonne. Cependant, j'accepte la réponse de @COLDSPEED qui inclut l'application spécifique à mes données. Mais certainement upvoting cela aussi bien. – PJW

1

Bien que la réponse acceptée est correcte dans la conversion de DOY datetime, il y a une petite erreur qui a été négligé.

À minuit le 1er janvier de chaque année, DOY 1.0. Comme vous procédez avec DOY temps fractionnaire, Jan 1 12:00 est DOY 1,5, Jan 2 00:00 est DOY 2.0, etc ...

Si vous ajoutez l'heure DOY à une date de décalage de base, comme suggéré dans les deux réponses ci-dessus, le temps résultant est décalé vers l'avant d'un jour. Par exemple, pd.to_datetime('2011-01-01') + pd.to_timedelta(df.DOY, unit='D'), avec une série DOY commençant par 1.0, la date de début du '2011-01-02' est incorrecte. Ceci est le résultat de la convention que DOY time commence par 1 au lieu de 0. Voir here pour plus d'informations.

Par conséquent, la bonne réponse (produisant des résultats corrects Datetime) est:

df.DOY = pd.to_datetime('2011-1-1') + pd.to_timedelta(gps.DOY, unit='D') - pd.Timedelta(days=1)