python - create - Reindexing series temporales de pandas desde el tipo de objeto a datetime dtype
string to datetime python (1)
Puede usar pd.to_datetime
:
In [1]: import pandas as pd
In [2]: pd.to_datetime(''2008-02-27'')
Out[2]: datetime.datetime(2008, 2, 27, 0, 0)
Esto le permite "limpiar" el índice (o similarmente una columna) al aplicarlo a la Serie:
df.index = pd.to_datetime(df.index)
o
df[''date_col''] = df[''date_col''].apply(pd.to_datetime)
Tengo una serie temporal que no se reconoce como DatetimeIndex a pesar de estar indexada por cadenas estándar AAAA-MM-DD con fechas válidas. Coaccionarlos a un DatetimeIndex válido parece ser lo suficientemente poco elegante como para hacerme pensar que estoy haciendo algo mal.
Leo en (los datos de otra persona formateados perezosamente) que contiene valores de fecha y hora no válidos y elimino estas observaciones inválidas.
In [1]: df = pd.read_csv(''data.csv'',index_col=0)
In [2]: print df[''2008-02-27'':''2008-03-02'']
Out[2]:
count
2008-02-27 20
2008-02-28 0
2008-02-29 27
2008-02-30 0
2008-02-31 0
2008-03-01 0
2008-03-02 17
In [3]: def clean_timestamps(df):
# remove invalid dates like ''2008-02-30'' and ''2009-04-31''
to_drop = list()
for d in df.index:
try:
datetime.date(int(d[0:4]),int(d[5:7]),int(d[8:10]))
except ValueError:
to_drop.append(d)
df2 = df.drop(to_drop,axis=0)
return df2
In [4]: df2 = clean_timestamps(df)
In [5] :print df2[''2008-02-27'':''2008-03-02'']
Out[5]:
count
2008-02-27 20
2008-02-28 0
2008-02-29 27
2008-03-01 0
2008-03-02 17
Este nuevo índice todavía solo se reconoce como un tipo de "objeto" en lugar de un DatetimeIndex.
In [6]: df2.index
Out[6]: Index([2008-01-01, 2008-01-02, 2008-01-03, ..., 2012-11-27, 2012-11-28,
2012-11-29], dtype=object)
Reindexar produce NaNs porque son diferentes dtypes.
In [7]: i = pd.date_range(start=min(df2.index),end=max(df2.index))
In [8]: df3 = df2.reindex(index=i,columns=[''count''])
In [9]: df3[''2008-02-27'':''2008-03-02'']
Out[9]:
count
2008-02-27 NaN
2008-02-28 NaN
2008-02-29 NaN
2008-03-01 NaN
2008-03-02 NaN
Creo un marco de datos nuevo con el índice apropiado, coloco los datos en un diccionario y luego rellena el nuevo marco de datos en función de los valores del diccionario (omitiendo los valores faltantes).
In [10]: df3 = pd.DataFrame(columns=[''count''],index=i)
In [11]: values = dict(df2[''count''])
In [12]: for d in i:
try:
df3.set_value(index=d,col=''count'',value=values[d.isoformat()[0:10]])
except KeyError:
pass
In [13]: print df3[''2008-02-27'':''2008-03-02'']
Out[13]:
count
2008-02-27 20
2008-02-28 0
2008-02-29 27
2008-03-01 0
2008-03-02 17
In [14]: df3.index
Out[14];
<class ''pandas.tseries.index.DatetimeIndex''>
[2008-01-01 00:00:00, ..., 2012-11-29 00:00:00]
Length: 1795, Freq: D, Timezone: None
Esta última parte de la configuración de valores basada en búsquedas para un diccionario codificado por cadenas parece especialmente hacky y me hace pensar que me he perdido algo importante.