[Python] Beschleunigt das Laden von Zeitreihen-CSV

Bei der Analyse von Zeitreihendaten lesen Sie häufig Daten aus CSV / TsV-Dateien.

Wenn die Datei eine Kapazität hat, die in einige zehn MB passt, ist es Ihnen vielleicht egal, aber wenn es sich um eine Datei mit einigen hundert MB handelt, dauert das Lesen nur einige Sekunden bis einige zehn Sekunden, und jedes Mal, wenn Sie den Code ausführen, dauert es einige Sekunden bis einige zehn Sekunden. Die Zeit wird stressig.

Hier werden wir eine Methode vorstellen, die den Lesevorgang mit ein wenig Einfallsreichtum explodieren lässt.

Ausführungsumgebung

Messen Sie die Ausführungszeit mit dem vorliegenden MBP.

MacBook Pro (Retina, 13-inch, Mid 2014)

Darüber hinaus ist die Ausführungsumgebung des Messcodes die neueste Version der 2.7-Serie.

$ python --version
$ Python 2.7.10

Verwenden Sie das Pandas-Modul, um die CSV-Datei zu lesen.

>>> import pandas
>>> pandas.__version__
0.18.1

Die zu lesende CSV-Datei verwendet die Daten des Dollar-Yen-Wechselkurses in Schritten von 1 Minute von 2005 bis 2015, die gerade zur Hand waren. Enthält Daten in 5 Zeitspalten, offenen Preis, hohen Preis, niedrigen Preis und Schlusspreis x 3687221 Zeilen.

Der Inhalt ist so

time open high low close
2005-01-03 03:00:00 102.360 102.390 102.360 102.390
$ wc -c < usdjpy-1m.csv
204760049

Es ist eine CSV-Datei von etwa 204 MB.

0 ・ Vorbereitung

Verwenden Sie die "Zeit" -Methode des Standardmoduls "Zeit", um die Zeit zu messen. Ich habe den folgenden Code vorbereitet, um mich darauf vorzubereiten.

Die calctime Methode ist eine einfache Messmethode, die einen beliebigen Ausdruck ausführt und die Differenz zwischen der Startzeit und der Endzeit zurückgibt.

calctime.py


#!/usr/bin/python
# -*- encoding: utf-8 -*-

from time import time

def calctime(func):
	start = time()
	r = func()
	return {'value': r, 'time': time()-start}

1. Normal lesen

Verwenden Sie zum Messen der Referenzzeit zunächst die Methode "read_csv", um die Zeit zu messen.

calctime.py


import pandas

csv = calctime(lambda: pandas.read_csv('usdjpy-1m.csv'))
print('Normal lesen_csv{}Es dauerte eine Sekunde'.format(csv['time']))
Normal lesen_CSV 7.56608009338 dauerte 2 Sekunden

Es dauert 7,5 Sekunden. Da es sich bei der diesmal behandelten Datei um Zeitreihendaten handelt, analysiere ich außerdem die Spalte, in der die Zeit gespeichert ist, nach dem Datum / Uhrzeit-Typ.

calctime.py


import pandas

csv = calctime(lambda: pandas.read_csv('usdjpy-1m.csv', parse_dates=['time'], index_col='time'))
print('Lesen Sie, während Sie die Zeitspalte analysieren_csv{}Es dauerte eine Sekunde'.format(csv['time']))
Lesen Sie, während Sie die Zeitspalte analysieren_40 mit csv.0371601582 Es dauerte 2 Sekunden

Es dauert 40 Sekunden. Ich kann nicht davon sprechen, jedes Mal 40 Sekunden zu warten, also beschleunigen wir es.

2. Serialisieren Sie das Objekt

Python wird standardmäßig mit einem Modul namens "pickle" geliefert, das Objekte im Speicher in Bytes serialisiert.

Als Name des singulären Systems von Pickles bietet es eine Funktion zum Konvertieren eines Kurzzeitobjekts im Speicher in eine Form, die in eine Datei ausgegeben und im Speicher gespeichert werden kann. Rohes Gemüse kann auch eingelegt und lange gelagert werden.

Der Code sieht so aus.

Speichern Sie das in der Variablen gespeicherte Objekt mit pandas.read_csv als usdjpy-1m.csv.pkl mit pickle.dump im Speicher und lesen Sie die Dumped-Byte-Zeichenfolge mit pickle.load. Ich messe die Zeit.

calctime.py


import pandas
import pickle

#Laden von csv
csv = pandas.read_csv('usdjpy-1m.csv', parse_dates=['time'], index_col='time')

#Bytes in Datei sichern
pickle.dump(csv, open('usdjpy-1m.csv.pkl', 'w'))

#Laden Sie die abgelegte Datei neu
pickled = calctime(lambda: pickle.load(open('usdjpy-1m.csv.pkl', 'w')))
print('Beim Laden mit Gurke{}Es dauerte eine Sekunde'.format(pickled['time']))
5 beim Laden mit Gurke.65008401871 dauerte 1 Sekunde

Es wurde stark von 40 Sekunden auf 5,6 Sekunden reduziert.

Es scheint, dass es funktioniert, da es nicht mehr erforderlich ist, den Datum / Uhrzeit-Typ jedes Mal zu analysieren.

Sobald Sie es mit Gurke entsorgt haben, können Sie es als Pandas-Objekt verwenden, indem Sie es beim nächsten Mal lesen, sodass es einfach ist. Ich habe große Fortschritte gemacht.

Aber es ist lang genug, um jedes Mal 5,6 Sekunden zu warten. Lassen Sie uns diese Gurke noch schneller machen.

3. Geben Sie das Pickle-Protokoll an

Wie in [http://docs.python.jp/2/library/pickle.html#pickle.dump] gezeigt (http://docs.python.jp/2/library/pickle.html#pickle.dump) , Pickle kann das Protokoll angeben, das beim Dumping verwendet werden soll.

Es gibt die Versionen 0 bis 2 des Protokolls, wobei 0 die älteste und langsamste und 2 die neueste und schnellste ist. Version 2 kann nur in Python 2.3 oder höheren Umgebungen verwendet werden und hat die Funktion, nicht abwärtskompatibel zu sein.

Und die Standardeinstellung ist Version 0. Wenn Sie "pickle.dump" verwenden, ohne etwas anzugeben, verwenden Sie am Ende ein langsames Protokoll anstelle der Abwärtskompatibilität.

Geben Sie das Protokoll im obigen Code an und führen Sie es erneut aus.

calctime.py


import pandas
import pickle

#Laden von csv
csv = pandas.read_csv('usdjpy-1m.csv', parse_dates=['time'], index_col='time')

#Speichern Sie Bytes mithilfe des Protokolls der Version 2 in die Datei
pickle.dump(csv, open('usdjpy-1m.csv.pkl', 'w'), protocol=2)

#Laden Sie die abgelegte Datei neu
pickled = calctime(lambda: pickle.load(open('usdjpy-1m.csv.pkl', 'w')))
print('Mit Version 2{}Es dauerte eine Sekunde'.format(pickled['time']))
1 mit Version 2.07643604279 Es dauerte 2 Sekunden

5,6 Sekunden → Es wurde auf ca. 1 Sekunde verkürzt. Sie können jetzt mit einer schönen Geschwindigkeit lesen.

Aber ich bin immer noch nicht zufrieden. Jedes Mal 1 Sekunde zu warten ist stressig.

Fügen wir zum Schluss noch einen weiteren Versuch hinzu, um den Code zu explodieren.

4. Speichern Sie die Gurke in Redis

Wenn Sie die von pickle ausgegebene Byte-Zeichenfolge als Datei im Speicher speichern, dauert das Lesen einige Zeit.

Umgekehrt bedeutet die Tatsache, dass die Zugriffszeit auf den Speicher ein Engpass ist, dass sie beseitigt werden sollte.

Hier ändern wir das Speicherziel in redis, wodurch Daten im Speicher anstatt im Speicher gespeichert werden.

redis ist eine Datenbank mit Schlüsselwertspeichertyp, die im Arbeitsspeicher ausgeführt wird und die Eigenschaft hat, extrem schnell zu sein, da sie Daten im Arbeitsspeicher speichert.

Detaillierte Installationsmethoden und Erklärungen werden hier weggelassen. Bitte überprüfen Sie sie, wenn Sie interessiert sind.

Funktioniert redis bei erfolgreicher Installation ordnungsgemäß?

$ redis-cli ping
PONG

Sie können dies überprüfen, indem Sie den Befehl eingeben.

Um von Python aus auf Redis zuzugreifen, installieren Sie das Modul "Redis" mit pip.

$ pip install redis

Lassen Sie uns den vorherigen Code ein wenig ändern, die gelesene CSV als Byte-Zeichenfolge zum Speichern und Redis speichern und dann die Zeit messen, um sie von Redis abzurufen.

Dieses Mal wird weder Dump noch Laden durch Angabe einer Datei ausgeführt, aber ich möchte sie zu einer Variablen erweitern, sodass die verwendeten Methoden "pickle.dumps" und "pickle.loads" sind.

calctime.py


import pandas
import pickle
import redis

#Laden von csv
csv = pandas.read_csv('usdjpy-1m.csv', parse_dates=['time'], index_col='time')

#Dump-Bytes mit dem Protokoll der Version 2
dumped = pickle.dumps(csv, protocol=2)

#Speichern Sie die ausgegebene Byte-Zeichenfolge in redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.set('usdjpy-1m.csv', dumped)

#Lesen Sie die Bytes von Redis und stellen Sie sie mit pickle wieder her
csv = calctime(lambda: pickle.loads(r.get('usdjpy-1m.csv')))
print('Mit Redis{}Es dauerte eine Sekunde'.format(csv['time']))
0 mit Redis.Es dauerte 332698106766 Sekunden

Es wurde von 1 Sekunde auf 0,33 Sekunden reduziert.

Damit können Sie den Code stressfrei ausführen! Im Vergleich zu den ersten 40 Sekunden des Ladens war es 121-mal schneller.

Bonus

Hier ist der im Experiment verwendete Codesatz.

calctime.py


#!/usr/bin/python
# -*- encoding: utf-8 -*-

import pandas
import pickle
import redis
from time import time

#Zeitmessmethode
def calctime(func):
	start = time()
	r = func()
	return {'value': r, 'time': time()-start}

#CSV-Dateipfad
csv_filepath = 'usdjpy-1m.csv'

#Normal lesen
read_csv = calctime(lambda: pandas.read_csv(csv_filepath, parse_dates=['time'], index_col='time'))
print('Normal lesen_csv{}Es dauerte eine Sekunde'.format(read_csv['time']))

#pickle Mit Protocolol Version 0 lesen
pickle.dump(read_csv['value'], open('csv0.pkl', 'w'))
pickle_load_0 = calctime(lambda: pickle.load(open('csv0.pkl', 'r')))
print('Gurke mit Protocolol Version 0{}Es dauerte eine Sekunde'.format(pickle_load_0['time']))

#pickle Read mit Protocolol Version 2
pickle.dump(read_csv['value'], open('csv2.pkl', 'w'), protocol=2)
pickle_load_2 = calctime(lambda: pickle.load(open('csv2.pkl', 'r')))
print('Mit pickle Protocolol Version 2{}Es dauerte eine Sekunde'.format(pickle_load_2['time']))

#Lesen Sie mit Redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.set(csv_filepath, pickle.dumps(read_csv['value'], protocol=2))
redis_get = calctime(lambda: pickle.loads(r.get(csv_filepath)))
print('Mit Redis{}Es dauerte eine Sekunde'.format(redis_get['time']))

Schließlich

Ich denke, dass es bei der Analyse von Daten viele Situationen gibt, in denen Sie den Code viele Male ausführen und Versuche und Fehler wiederholen müssen, aber ich hoffe, dass es Ihnen dabei hilft, die Iterationen in solchen Fällen so effizient wie möglich zu drehen.

Der Autor veröffentlicht täglich technische Informationen auf Twitter. Ich wäre Ihnen dankbar, wenn Sie mir folgen könnten.

https://twitter.com/YuhsakInoue

Recommended Posts

[Python] Beschleunigt das Laden von Zeitreihen-CSV
Python: Zeitreihenanalyse
Python-Zeitreihenfrage
Zeichnen Sie die CSV von Zeitreihendaten mit einem Unixtime-Wert in Python (matplotlib).
[Python] Zeichnen Sie Zeitreihendaten
Beschleunigen Sie das Laden von Python-Bildern
[Python] Laden von CSV-Dateien mit Pandas
Berechnung der Zeitreihen-Kundenbindung
Python: Zeitreihenanalyse: Vorverarbeitung von Zeitreihendaten
Zeitdelta in Python 2.7-Serie teilen
Zeitreihenplot gestartet ~ Python Edition ~
Differenzierung von Zeitreihendaten (diskret)
Zeitreihenanalyse 3 Vorverarbeitung von Zeitreihendaten
Zeitreihenanalyse 4 Konstruktion des SARIMA-Modells
Grundlegende Grammatik der Python3-Reihe (Liste, Tapple)
Einfache Einführung in die Python3-Serie und OpenCV3
Python: Zeitreihenanalyse: Erstellen eines SARIMA-Modells
Holen Sie sich mit Python Zeitreihendaten von k-db.com
Erster Python
Zeitmessung
Python: Zeitreihenanalyse: Konstanz, ARMA / ARIMA-Modell
Zeitreihenzerlegung
Zeichenkodierung bei Verwendung des CSV-Moduls von Python 2.7.3
Grundlagen von Python ①
Erster Python
Glättung von Zeitreihen und Wellenformdaten 3 Methoden (Glättung)
Kopie von Python
Zeigen Sie Details zu Zeitreihendaten mit Remotte an
CSV in Python
Zum Zeitpunkt des Python-Updates mit Ubuntu
Erstellen Sie mit Python + Plotly eine animierte Zeitreihenkarte des Infektionsstatus des Corona-Virus
Geschwindigkeitsbewertung der Ausgabe von CSV-Dateien in Python
Beispiel für das Lesen und Schreiben von CSV mit Python
Einführung von Python
Grundlegende Bedienung von Python Pandas Series und Dataframe (1)
Implementierung der Clustering-K-Form-Methode für Zeitreihendaten [Unüberwachtes Lernen mit Python Kapitel 13]
Verarbeitung von CSV-Daten in voller und halber Breite in Python
Zusammenfassung der Python-Sortierung (Liste, Wörterbuchtyp, Serie, DataFrame)
Python 3.4 Windows7-64bit-Umgebung erstellen (für die Analyse finanzieller Zeitreihen)
Abnormalitätserkennung von Zeitreihendaten durch LSTM (Keras)
Speichern Sie TOPIX-Zeitreihen im Pickle-, CSV- und Excel-Format
[Zeitreihen mit Handlung] Dynamische Visualisierung mit Handlung [Python, Aktienkurs]
[Python] Operation der Aufzählung
Liste der Python-Module
Funktionsausführungszeit (Python)
Vereinheitlichung der Python-Umgebung
Kopie der Python-Einstellungen
Grundlagen der Python-Scraping-Grundlagen
[Python] Verhalten von Argmax
"Zeitreihenanalyse von Wirtschafts- und Finanzdaten messen" Das Problem am Ende des Kapitels mit Python lösen
Verwendung von Python-Einheimischen ()
der Zen von Python
Installieren von Python 3.3 rc1
RNN_LSTM1 Zeitreihenanalyse
Zeitreihenanalyse 1 Grundlagen
Ausführungszeit für Python ausgeben
So berechnen Sie die Summe oder den Durchschnitt von Zeitreihen-CSV-Daten in einem Augenblick
Timefloor-Funktion (Python)