Angenommen, Sie diesen Satzart in PyTables definiert haben
class Record(tables.IsDescription):
row = tables.Int32Col()
col1 = tables.Int32Col()
col2 = tables.Float64Col()
col3 = tables.Float64Col()
Eine regelmäßige Bereichsabfrage könnte wie folgt aussehen:
result = [rec for rec in table if (rec['row'] > 100 and rec['row'] < 200)]
Dieses feinen Ihre Tabelle funktioniert nicht zu groß ist. Für große Tabellen wird es jedoch relativ langsam sein, da jede Zeile in den Python-Raum gebracht werden muss, um für die Bereichsbedingung ausgewertet zu werden.
Um diese Abfrage zu beschleunigen man auf die so genannte im Kernel Abfragen verlassen kann, die die Bedingung mit einem PyTables Kernel überprüfen können, die mit Hilfe der numexpr Bibliothek in C geschrieben wird.
result = [rec for rec in table.where(
'row > 100 & row < 200')]
Sie können auch eine regelmäßige Abfrage mit einer in-kernel Abfrage mischen und:
result = [rec for rec in table.where(
'row > 100 & row < 200')] if your_function(rec['col2']) ]
Wenn Sie große Tabellen, die in den Speicher passen nicht der Speedup um 2x ist. Die Verwendung von Komprimierung (d. H. BLOSC, LZF usw.) führt zu einer leichten Geschwindigkeitssteigerung, da der CPU-Overhead des Dekomprimierens geringer ist als der I/O-Overhead (verwenden Sie also die Komprimierung für große Tabellen, die nicht in den Speicher passen).
Wenn Sie die Komprimierung verwenden, wird das Dataset in Chunks aufgeteilt und die Chunks werden separat komprimiert. Das heißt, wenn Sie nach einem bestimmten Bereich (Zeilen 100 - 200) fragen, werden die entsprechenden komprimierten Blöcke von der Festplatte in den Speicher geladen und dann von der CPU im Speicher dekomprimiert. Dies wird die Geschwindigkeit im Vergleich zur Verwendung ohne Komprimierung oder zum kontinuierlichen Speichern des Datasets beschleunigen. Blosc
ist ein Meta-Kompressor und lzf
ist der Standardkompressor von h5py. Für Unterschiede zwischen Blosc
und lzf
siehe thread.
Wenn die In-Kernel-Abfragen nicht schnell genug sind, können Sie auch einen Index für eine oder mehrere Spalten erstellen. Auf diese Weise wird die Abfrage eine binäre Suche anstelle einer sequenziellen Suche verwenden. So erstellen Sie führen einen Index für eine vorhandene Tabelle für die row
Spalte gerade:
indexrows = table.cols.row.create_index()
Aber Vorsicht, dass der Index nicht auf allen Bedingungen verwendet werden (siehe Referenz unten). Um zu überprüfen, ob Ihre Abfrage den Index ordnungsgemäß verwendet, können Sie die Methode Table.will_query_use_indexing() verwenden.
Quelle: http://www.pytables.org/usersguide/optimization.html#indexed-searches
PyTables unterstützt Indizes für Spalten (siehe [hier] (http://www.pytables.org/usersguide/optimization.html#indexed-searches) mit 'numexpr' mit dem OPSI. Index sollte schnell genug sein und sollte nicht alles in den Speicher zu lesen benötigen –
@ Ümit Thanks for this.Dies ist eigentlich eine ziemlich gute Idee.Können Sie ein schnelles Beispiel unten bieten? zB make-Tabelle, setzen OSPI-Indizes auf eine Hand voll von Spalten mit PyTables, benutze numexpr, um zu zeigen, wie dies gemacht wird, etc. Es ist einfacher zu folgen, und nützlich für StackExchange – ShanZhengYang
hinzugefügt eine Antwort –