Me gustaría obtener una regresión con una serie de tiempo como predictor y estoy tratando de seguir la respuesta de esta respuesta SO ( OLS con pandas: índice de fecha y hora como predictor ), pero ya no parece funcionar tan bien conocimiento.
¿Me estoy perdiendo algo o hay una nueva forma de hacer esto?
import pandas as pd rng = pd.date_range('1/1/2011', periods=4, freq='H') s = pd.Series(range(4), index = rng) z = s.reset_index() pd.ols(x=z["index"], y=z[0])
Estoy recibiendo este error. El error es explicativo, pero me pregunto qué me falta al volver a implementar una solución que funcionó antes.
TypeError: no se puede escribir un tipo de fecha de datos desde [datetime64 [ns]] a [float64]
No estoy seguro de por qué pd.ols
es tan delicado (me parece que pd.ols
el ejemplo correctamente). Sospecho que esto se debe a los cambios en la forma en que los pandas manejan o almacenan los índices de fecha y hora, pero soy demasiado perezoso para explorar esto más a fondo. De todos modos, dado que su variable datetime difiere solo en la hora, puede extraer la hora con un acceso dt
:
pd.ols(x=pd.to_datetime(z["index"]).dt.hour, y=z[0])
Sin embargo, eso le da una r cuadrada de 1, ya que su modelo está sobreespecificado con la inclusión de una intersección (yy es una función lineal de x). Podría cambiar el range
a np.random.randn
y luego obtendría algo que se parece a los resultados de una regresión normal.
In [6]: z = pd.Series(np.random.randn(4), index = rng).reset_index() pd.ols(x=pd.to_datetime(z["index"]).dt.hour, y=z[0]) Out[6]: -------------------------Summary of Regression Analysis------------------------- Formula: Y ~ + Number of Observations: 4 Number of Degrees of Freedom: 2 R-squared: 0.7743 Adj R-squared: 0.6615 Rmse: 0.5156 F-stat (1, 2): 6.8626, p-value: 0.1200 Degrees of Freedom: model 1, resid 2 -----------------------Summary of Estimated Coefficients------------------------ Variable Coef Std Err t-stat p-value CI 2.5% CI 97.5% -------------------------------------------------------------------------------- x -0.6040 0.2306 -2.62 0.1200 -1.0560 -0.1521 intercept 0.2915 0.4314 0.68 0.5689 -0.5540 1.1370 ---------------------------------End of Summary---------------------------------
Alternativamente, podría convertir el índice en un entero, aunque encontré que esto no funcionó muy bien (supongo que los enteros representan nanosegundos desde la época o algo así, y por lo tanto son muy grandes y causan problemas de precisión), pero la conversión a entero y la división por un billón o así funcionó y dio esencialmente los mismos resultados que al usar dt.hour
(es decir, el mismo r-cuadrado):
pd.ols(x=pd.to_datetime(z["index"]).astype(int)/1e12, y=z[0])
Fuente del mensaje de error
FWIW, parece que el mensaje de error proviene de algo como esto:
pd.to_datetime(z["index"]).astype(float)
Aunque una solución bastante obvia es esta:
pd.to_datetime(z["index"]).astype(int).astype(float)