J'ai un dictionnaire qui se compose d'un horodatage horaire (secondes depuis l'époque) au fur et à mesure de la clé, et d'un entier comme valeur pour chacun. Actuellement, j'ai une série incomplète d'heures de données horaires, et j'aimerais combler les lacunes.

Ce que je veux dire, c'est que si j'ai une entrée pour le 15/05/2015 17:00:00 et une entrée pour le 15/05/2015 19:00:00, mais rien pour le 15/05/2015 18:00:00, y a-t-il un moyen d'itérer et de remplir rapidement ces clés horaires manquantes avec une valeur de, disons, «0».

J'ai une grande quantité de données de texte brut qui comprend des dates dans ce format: AAAA-mm-JJ HH: MM: SS, que j'arrondis à l'heure (en convertissant en secondes depuis l'époque en utilisant datetime.datetime.strptime, et en tronquant le minutes et secondes), et comptez essentiellement le nombre de fois que chaque heure apparaît dans les données brutes. Mon dictionnaire ressemble donc à {'2015-04-02 04:00:00': 1, '2015-06-06 13:00:00': 4, ...}. Il y a des lacunes horaires et j'aimerais les combler rapidement et efficacement.

Ma solution actuelle consiste à trouver le minimum des clés du dictionnaire, à créer un tout nouveau dictionnaire et à le remplir toutes les heures jusqu'au maximum du dictionnaire d'origine. ALORS je viens de refaire le code que j'ai écrit pour créer le dictionnaire original, qui change les valeurs qui ont des données à changer, mais laisse les valeurs «vides» à 0. Évidemment pas élégant ...

1
Mirza 21 juil. 2015 à 00:26

2 réponses

Meilleure réponse

Une solution pourrait être:

import datetime

# your dictionnary
data = {...}

start = datetime.datetime.fromtimestamp(0)
step = datetime.timedelta(seconds=3600)

stop = datetime.datetime.now()
while start <= stop:
    key = start.strftime('%d/%m/%Y %H:%M:%S')
    if key not in data:
        data[key] = 0
    start+= step

Mais vaut-il la peine de combler les lacunes? ou votre cas d'utilisation serait collections.defaultdict?

Exemple:

>>> data = collections.defaultdict(int)
>>> print data['5/15/2015 17:00:00']
0
4
bufh 20 juil. 2015 à 21:41

Vous pouvez étendre la classe dict par quelque chose comme ceci:

class FilledDict(dict):

    def __missing__(self, i):
        if any(k < i for k in self.keys()) and any(k > i for k in self.keys()):
            return 0
        raise KeyError()

Puis utilisez-le comme n'importe quel dict:

In [2]: fd = FilledDict()

In [3]: fd[2] = 3

In [4]: fd[4] = 5

In [5]: fd[1]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-5-e8f6ba432654> in <module>()
----> 1 fd[1]

/tmp/ipython_edit_lfgvSO/ipython_edit_OrM6Oj.py in __missing__(self, i)
      4         if any(k < i for k in self.keys()) and any(k > i for k in self.keys()):
      5             return 0
----> 6         raise KeyError()

KeyError: 

In [6]: fd[3]
Out[6]: 0

Il peut être intéressant de noter que vous pouvez convertir n'importe quel dict en un FilledDict:

In [10]: d = dict(a=1, b=2)

In [11]: fd = FilledDict(d)

In [12]: fd
Out[12]: {'a': 1, 'b': 2}
3
matiasg 20 juil. 2015 à 22:10