2017-10-02 1 views
1

Disons que j'ai une liste de dates au format datetime.date. Je souhaite transformer la date en mois en périodes discrètes (entières).Transformer le mois en périodes de temps discrètes

Ie,

myList = [datetime.date(2015,02,08), datetime.date(2015,02,25), datetime.date(2015,05,03), datetime.date(2016,03,27)] 

Depuis la plus petite année/mois est 2015/02 alors que le mois est équivalent à 0. Le mois suivant 2015/03 serait 1, etc. Jusqu'au mois dernier 2016/03 serait être 13.

Je voudrais une fonction pour laquelle je lui donne la date de début, et puis il me donne le mois discret.

à savoir,

discretizeMo(start_date, date_of_interest) 
discretizeMo('2012-02-01', '2013-01-01') 

retourneraient 11, etc.

Répondre

1

Eh bien, puisque vous déposez les jours, l'arithmétique date habituelle est d'aucune utilité ici. La solution la plus simple serait de convertir des années & mois à une échelle:

def discretizeMo(d1, d2): 
    return (d2.year * 12 + d2.month) - (d1.year * 12 + d1.month) 

Le résultat est le nombre de mois écoulés depuis la date d1 jusqu'à la date d2.

C'est simple.

Si vous voulez le diviser en plus petites unités de longueur fixe (par exemple, des semaines), il sera différent:

def discretizeMo(d1, d2): 
    return (d2 - d1).days // 7 

La différence vient de la durée variable de mois en jours: 28-29- 30-31.

+0

Et si je voulais discrétiser le temps en semaines? puis une année a 52 semaines ... mais je suppose que ça devient un peu plus compliqué ... – Dnaiel

+1

@Dnaiel Ajout de la réponse pour les semaines. Les mathématiques seront différentes dans ce cas. Parce que les mois ont un nombre variable de jours, les "maths de l'année-mois" et "les maths de jour" sont différents. –

+1

Cela fonctionne, mais il repose de manière assez subtile sur le fait que les timedeltas en Python sont normalisées dans une représentation unique de jours, secondes, microsecondes. – wim

1

C'est assez facile, car il y aura toujours 12 mois en un an:

def discretizeMo(d0, d): 
    return (d.year - d0.year)*12 + d.month - d0.month 

Si vous avez affaire à plusieurs fuseaux horaires, vous pouvez vous assurer que d0 et d ont le même fuseau horaire , sinon vous pourriez obtenir des résultats incorrects.

+0

J'essaie de trouver une formule générale, et si je voulais les discrétiser en semaines? – Dnaiel

+0

Le résultat dépend du jour où vous considérez le début de la semaine. Donc, vous devez prendre une décision à ce sujet, d'abord. – wim

+0

bon point. c'est vrai disons que le jour est le jour de la date de début que nous utilisons comme d0. C'est-à-dire, pour notre exemple ce serait datetime.date (2015,02,08) et ce serait le jour 0, la semaine 0. – Dnaiel

2

Vous pouvez soustraire les parties de l'année, il faut multiplier par 12 pour obtenir la différence de mois, puis soustraire les parties mois:

def discretizeMo(start_date, end_date): 
    return (end_date.year - start_date.year) * 12 + \ 
      (end_date.month - start_date.month) 

A partir de là, il est juste une question d'appliquer cette fonction entre chaque élément et le minimum:

result = [discretizeMo(min(myList), x) for x in myList] 
+0

et si je voulais le discrétiser en semaines par exemple? J'essaie d'utiliser une formule générale ... – Dnaiel