2016-06-10 13 views
1

Ich arbeite daran, ein Futures-Markt-Tick-Daten-Replay-System mit Python und Pytables mit einem ziemlich großen Datensatz (+ 200 GB) zu machen.Beschleunigung der Konvertierung von Zeitstempel zu Datetime Python

Soweit ich das beurteilen kann, können pytables nur numpy datetime64 Objekte für meine Zeitstempel speichern. Dies ist ein Problem, da ich sie in Datetime-Objekte oder Pandas-Timestamps konvertieren muss, damit das Handelsmodul Methoden wie Uhrzeit oder Wochentag oder Monat für die eingehenden Daten aufrufen kann. Der Versuch, Milliarden von Zeilen zur Laufzeit zu konvertieren, macht das System grundsätzlich unbrauchbar.

pd.to_datetime(my_datetime64) 
datetime.datetime(my_datetime64) 

sind beide viel zu langsam.

hier ist, wie ich meine Tausende von rohen csvs in den Pytables Store importieren. Beachten Sie, dass der Index in dem Pandas Datetime-Format ist, die mir Informationen über die Zeitstempel wie Zeit, Monat, Jahr etc.

from pandas import HDFStore 
store = HDFStore(store_dir) 

for file in files: 
      df = pd.read_csv("/TickData/"+file) 
      df.index = pd.to_datetime(df['date'].apply(str) + " " + df['time'], format = '%Y%m%d %H:%M:%S.%f') 
      df.drop(['date', 'time'], axis=1, inplace=True) 
      store.append('ticks', df, complevel=9, complib='blosc') 

hier, was die Daten aussehen, wenn ich las wieder ein Stück mit dem PyTables Tisch zu bekommen erlaubt .lesen Methode - kann man sehen, dass die Pandas Zeitstempel alle

array([(1220441851000000000, [b'ESU09'], [1281.0], [1]), 
     (1226937439000000000, [b'ESU09'], [855.75], [2]), 
     (1230045292000000000, [b'ESU09'], [860.0], [1]), ..., 
     (1244721917000000000, [b'ESU09'], [943.75], [1]), 
     (1244721918000000000, [b'ESU09'], [943.75], [2]), 
     (1244721920000000000, [b'ESU09'], [944.0], [15])], 
     dtype=[('index', '<i8'), ('values_block_0', 'S5', (1,)), ('values_block_1', '<f8', (1,)), ('values_block_2', '<i8', (1,))]) 

hier datetime64 in umgewandelt wurde, wie ich sie aus der Tabelle in Stücke lesen

chunksize = 100000 
    nrows = 1000000000 
    n_chunks = nrows//chunksize + 1 
    h5f = tables.open_file(store_directory, 'r') 
    t = h5f.get_node('/', 'ticks') 

    for i in range(n_chunks): 
     chunk = t.table.read(i*chunksize, (i+1)*chunksize) 
      for c in chunk: 
        #this is where we would convert c[0] which is the timestamp , 
pd.to_datetime(c[0]) or datetime.datetime(c[0]), both are too slow 

Meine Frage ist letztlich:

1: Gibt es einen schnelleren Weg, die datetime64 zurück in Datums- oder Pandas Zeitstempel zu konvertieren, vielleicht etwas mit Cython zu tun?

ODER 2: Gibt es eine Möglichkeit, die Pandas-Zeitstempel im HDF zu speichern, damit sie beim Lesen nicht konvertiert werden müssen?

Dank

+0

Wie einzigartig sind Ihre Zeitstempel und was ist die Auflösung? – rrauenza

+0

@rrauenza, Sie sind wahrscheinlich 85% einzigartig, Millisekunden-Auflösung –

+0

Ok, würde vorschlagen, lru memoization, wenn die Werte wiederholt werden. – rrauenza

Antwort

2

Versuchen Sie folgendes:

import numpy 
from datetime import datetime 

npdt = numpy.datetime64(datetime.utcnow()) 
dt = npdt.astype(datetime) 

Ich fand es schneller eine Größenordnung sein:

from datetime import datetime 
import numpy 
import pandas 
import timeit 

foo = numpy.datetime64(datetime.utcnow()) 
print(foo.astype(datetime)) 
print(pandas.to_datetime(foo)) 

print(timeit.timeit('foo.astype(datetime)', setup='import numpy; import pandas; from datetime import datetime; foo = numpy.datetime64(datetime.utcnow())')) 
print(timeit.timeit('pandas.to_datetime(foo)', setup='import numpy; import pandas; from datetime import datetime; foo = numpy.datetime64(datetime.utcnow())')) 

Ausgang:

2016-06-10 20:51:11.745616 
2016-06-10 20:51:11.745616 
1.916042190976441 
37.38387820869684 
+0

Ich werde Gib mir dies, wenn ich nach Hause komme, danke! –

+0

Ich habe diese Frage als Referenz verwendet: http://stackoverflow.com/questions/13703720/converting-between-datetime-timestamp-and-datetime64 – rrauenza