PANDAS -Zeitreihen -Optimierungsproblem: Jahr hinzufügen
Frage
Ich habe einen PANDAS -Datenfreame, der eine Zeitreihenspalte enthält. Die Jahre werden in der Vergangenheit verschoben, so dass ich jedem Element dieser Spalte eine konstante Anzahl von Jahren hinzufügen muss.
Der beste Weg, den ich fand, besteht darin, alle Datensätze durchzusetzen und zu verwenden
x.replace(year=x.year + years) # x = current element, years = years to add
Es ist wie unten Cythonized, aber immer noch sehr langsam (Proofing)
cdef list _addYearsToTimestamps(list elts, int years):
cdef cpdatetime x
cdef int i
for (i, x) in enumerate(elts):
try:
elts[i] = x.replace(year=x.year + years)
except Exception as e:
logError(None, "Cannot replace year of %s - leaving value as this: %s" % (str(x), repr(e)))
return elts
def fixYear(data):
data.loc[:, 'timestamp'] = _addYearsToTimestamps(list(data.loc[:, 'timestamp']), REAL_YEAR-(list(data[-1:]['timestamp'])[0].year))
return data
Ich bin mir ziemlich sicher, dass es eine Möglichkeit gibt, das Jahr ohne Iteration zu verändern, indem sie Pandas 'Zeitstempelfunktionen verwenden. Leider finde ich nicht wie. Könnte jemand näher erläutern?
Lösung
Machen Sie ein Pandas Timedelta -Objekt und fügen Sie mit dem += Operator hinzu:
x = pandas.Timedelta(days=365)
mydataframe.timestampcolumn += x
Der Schlüssel ist also, Ihre Zeitreihe als Zeitstempel zu speichern. Verwenden Sie dazu die Pandas to_datetime
Funktion:
mydataframe['timestampcolumn'] = pandas.to_datetime(x['epoch'], unit='s')
Angenommen, Sie haben Ihre Zeitstempel als Epoche Sekunden im DataFrame x
. Das ist natürlich keine Voraussetzung; Siehe das to_datetime Dokumentation zum Konvertieren anderer Formate.
Andere Tipps
Angepasst aus der Antwort von Pete hier eine Implementierung der Lösung und der Demonstration.
#!/usr/bin/env python3
import random
import pandas
import time
import datetime
def getRandomDates(n):
tsMin = time.mktime(time.strptime("1980-01-01 00:00:00", "%Y-%m-%d %H:%M:%S"))
tsMax = time.mktime(time.strptime("2005-12-31 23:59:59", "%Y-%m-%d %H:%M:%S"))
return pandas.Series([datetime.datetime.fromtimestamp(tsMin + random.random() * (tsMax - tsMin)) for x in range(0, n)])
def setMaxYear(tss, target):
maxYearBefore = tss.max().to_datetime().year
# timedelta cannot be given in years, so we compute the number of days to add in the next line
deltaDays = (datetime.date(target, 1, 1) - datetime.date(maxYearBefore, 1, 1)).days
return tss + pandas.Timedelta(days=deltaDays)
data = pandas.DataFrame({'t1': getRandomDates(1000)})
data['t2'] = setMaxYear(data['t1'], 2015)
data['delta'] = data['t2'] - data['t1']
print(data)
print("delta min: %s" % str(min(data['delta'])))
print("delta max: %s" % str(max(data['delta'])))