J'ai des fichiers HDF5 avec plusieurs groupes, où chaque groupe contient un ensemble de données avec> = 25 millions de lignes. À chaque étape de simulation, chaque agent produit les autres agents qu'il/elle a détectés à ce pas de temps. Il y a ~ 2000 agents dans le scénario et des milliers de pas de temps; la nature O (n^2) de la sortie explique le grand nombre de lignes.Python, PyTables - tirer parti de la recherche dans le noyau
Ce qui m'intéresse est de calculer le nombre d'observations uniques par catégorie. Par exemple, les agents appartiennent à un côté, rouge, bleu ou vert. Je veux faire une table bidimensionnelle où la rangée i, colonne j est le nombre d'agents dans la catégorie j
qui ont été détectés par au moins un agent dans la catégorie i. (J'utilise les côtés dans cet exemple de code, mais nous pouvons classer les agents d'autres façons, par exemple par l'arme qu'ils possèdent ou les capteurs qu'ils portent.)
Voici un exemple de tableau de sortie; Notez que la simulation ne produit pas de sensations bleu/bleu car cela prend énormément de place et ne nous intéresse pas. Idem pour le vert vert)
blue green red
blue 0 492 186
green 1075 0 186
red 451 498 26
Les colonnes sont
- tique - pas de temps
- sensingAgentId - id de l'agent faisant détection
- sensedAgentId - id de l'agent étant lu
- detRange - plage en mètres entre deux agents
- senseType - type énuméré pour quel type de détection a été effectué
Voici le code Je suis actuellement en utilisant pour ce faire:
def createHeatmap():
h5file = openFile("someFile.h5")
run0 = h5file.root.run0.detections
# A dictionary of dictionaries, {'blue': {'blue':0, 'red':0, ...}
classHeat = emptyDict(sides)
# Interested in Per Category Unique Detections
seenClass = {}
# Initially each side has seen no one
for theSide in sides:
seenClass[theSide] = []
# In-kernel search filtering out many rows in file; in this instance 25,789,825 rows
# are filtered to 4,409,176
classifications = run0.where('senseType == 3')
# Iterate and filter
for row in classifications:
sensedId = row['sensedAgentId']
# side is a function that returns the string representation of the side of agent
# with that id.
sensedSide = side(sensedId)
sensingSide = side(row['sensingAgentId'])
# The side has already seen this agent before; ignore it
if sensedId in seenClass[sensingSide]:
continue
else:
classHeat[sensingSide][sensedSide] += 1
seenClass[sensingSide].append(sensedId)
return classHeat
Note: J'ai un fond Java, donc je me excuse si ce n'est pas Pythonic. Veuillez le signaler et suggérer des façons d'améliorer ce code, j'aimerais devenir plus compétent avec Python. Maintenant, c'est très lent: cela prend environ 50 secondes pour faire cette vérification d'itération et d'appartenance, et ceci avec l'ensemble de critères d'appartenance le plus restrictif (les autres types de détection ont beaucoup plus de lignes à parcourir).
Ma question est, est-il possible de déplacer le travail de python et dans la requête de recherche dans le noyau? Si c'est le cas, comment? Y a-t-il des accélérations évidentes qui me manquent? Je dois être capable d'exécuter cette fonction pour chaque exécution dans un ensemble d'exécutions (~ 30), et pour plusieurs ensembles de critères (~ 5), donc ce serait génial si cela pouvait être accéléré. Note finale: J'ai essayé d'utiliser psyco mais cela a à peine fait une différence.
Pouvez-vous publier un fichier .h5 de test réduit? J'ai quelques idées, mais il serait plus facile de les vérifier avec des données semi-réelles. –