2010-03-28 5 views
3

Ceci est sans doute une autre question noobish, mais je vais le demander de toute façon:Nombre d'événements regroupés par date en python?

J'ai un ensemble de données d'événements avec datetime exacte en UTC. Je voudrais créer un graphique linéaire montrant le nombre total d'événements par jour (date) dans la plage de dates spécifiée. À l'heure actuelle, je peux récupérer le jeu de données complet pour la période de temps nécessaire, mais je dois ensuite passer en revue et compter pour chaque date.

L'application fonctionne sur google app engine et utilise python. Quelle est la meilleure façon de créer un nouvel ensemble de données montrant la date et les nombres correspondants (y compris s'il n'y avait aucun événement à cette date) que je peux utiliser pour transmettre cette information à un modèle django?

ensemble de données pour cet exemple ressemble à ceci:

class Event(db.Model): 
    event_name = db.StringProperty() 
    doe = db.DateTimeProperty() 
    dlu = db.DateTimeProperty() 
    user = db.UserProperty() 

Idéalement, je veux quelque chose avec la date et compter pour cette date.

Merci et s'il vous plaît laissez-moi savoir si quelque chose d'autre est nécessaire pour répondre à cette question!

Répondre

1

Vous devrez effectuer la binning en mémoire (c'est-à-dire après l'extraction de la banque de données).

La méthode .date() d'une instance datetime facilitera votre binning; il coupe l'élément temps. Ensuite, vous pouvez utiliser un dictionnaire pour contenir les bacs:

bins = {} 
for event in Event.all().fetch(1000): 
    bins.setdefault(event.doe.date(), []).append(event) 

faire ensuite ce que vous voulez avec (par exemple le nombre) les bacs. Pour un dénombrement direct:

counts = collections.defaultdict(int) 
for event in Event.all().fetch(1000): 
    counts[event.doe.date()] += 1 
+0

désolé, pouvez-vous élaborer un peu ou peut-être inclure un lien vers un tutoriel sur "binning"? Comment puis-je récupérer un compte pour dire 01/01/2010 à partir de "count"? – Sologoub

+0

Ummmm ... vous demandez comment extraire une valeur d'un dictionnaire? Quelque chose comme ceci: 'key = datetime.date (2010, 1, 1); the_answer = compte [clé] '... d'ailleurs, la réponse de @ kostmo est incomplète; Comme vous voulez en fin de compte une table qui comprend des comptes zéro, vous devez parcourir toute la plage de dates avant ou après le comptage. –

+0

@John Machin: En fait, dans mon deuxième extrait (le nombre direct), defaultdict retournera automatiquement "0" pour toute clé qui n'a pas été explicitement définie. – kostmo

0

Je ne vois pas comment cela serait possible avec une requête unique car GQL ne prend pas en charge GROUP BY ou aggregation en général.

+0

Cela ne peut pas être fait en GQL, mais j'espère que quelqu'un peut m'aider à le faire en mémoire – Sologoub

0

Afin de minimiser la quantité de travail que vous faites, vous aurez probablement envie d'écrire une tâche qui résume une fois les totaux par jour, afin que vous puissiez les réutiliser. Je suggère d'utiliser le bulkupdate library pour exécuter une tâche quotidienne qui compte les événements du jour précédent et crée une nouvelle instance de modèle, avec un nom de clé basé sur la date, contenant le nombre. Ensuite, vous pouvez obtenir tous les points de données nécessaires en faisant une requête (ou mieux, un lot obtenir) pour l'ensemble des entités de synthèse dont vous avez besoin.

+0

Merci Nick. Un problème est que je suis en train de mettre en place un moteur de reporting de base avec un certain nombre de filtres. J'ai pensé à construire des tables d'agrégation (sorte d'entrepôt de données?) Mais cela se fera à un stade ultérieur. En outre, google app engine offre une interface cronjob décent, donc l'exécution d'agrégations nocturnes ne devrait pas être difficile. – Sologoub

+0

Gardez à l'esprit que cronjobs seul ne le coupera pas pour les agrégations nocturnes si le nombre d'enregistrements à agréger devient trop élevé - d'où ma suggestion de la bibliothèque bulkupdate. –

Questions connexes