python - read - pandas to_sql mysql
Cómo escribir el marco de datos Pandas en sqlite con Index (3)
Tengo una lista de los datos del mercado de valores extraídos de Yahoo en un DataFrame de pandas (ver formato a continuación). La fecha sirve como el índice en el DataFrame. Quiero escribir los datos (incluido el índice) en una base de datos SQLite.
AAPL GE
Date
2009-01-02 89.95 14.76
2009-01-05 93.75 14.38
2009-01-06 92.20 14.58
2009-01-07 90.21 13.93
2009-01-08 91.88 13.95
Según mi lectura del código write_frame para Pandas, actualmente no es compatible con la escritura del índice . Intenté usar to_records en su lugar, pero encontré el problema con Numpy 1.6.2 y datetimes . Ahora estoy tratando de escribir tuplas usando .itertuples, pero SQLite produce un error que indica que el tipo de datos no es compatible (consulte el código y el resultado a continuación). Soy relativamente nuevo en Python, Pandas y Numpy, así que es completamente posible que me esté perdiendo algo obvio. Creo que tengo un problema al intentar escribir una fecha y hora en SQLite, pero creo que podría ser una complicación excesiva.
Creo que puedo solucionar el problema actualizando a Numpy 1.7 o la versión de desarrollo de Pandas, que tiene una solución publicada en GitHub. Preferiría desarrollar utilizando versiones de lanzamiento de software; soy nuevo en esto y no quiero que los problemas de estabilidad confundan aún más las cosas.
¿Hay alguna manera de lograr esto usando Python 2.7.2, Pandas 0.10.0 y Numpy 1.6.2? ¿Quizás limpiando las fechas de alguna manera? Estoy en un poco por encima de mi cabeza, cualquier ayuda sería apreciada.
Código:
import numpy as np
import pandas as pd
from pandas import DataFrame, Series
import sqlite3 as db
# download data from yahoo
all_data = {}
for ticker in [''AAPL'', ''GE'']:
all_data[ticker] = pd.io.data.get_data_yahoo(ticker, ''1/1/2009'',''12/31/2012'')
# create a data frame
price = DataFrame({tic: data[''Adj Close''] for tic, data in all_data.iteritems()})
# get output ready for database export
output = price.itertuples()
data = tuple(output)
# connect to a test DB with one three-column table titled "Demo"
con = db.connect(''c:/Python27/test.db'')
wildcards = '',''.join([''?''] * 3)
insert_sql = ''INSERT INTO Demo VALUES (%s)'' % wildcards
con.executemany(insert_sql, data)
Resultado:
---------------------------------------------------------------------------
InterfaceError Traceback (most recent call last)
<ipython-input-15-680cc9889c56> in <module>()
----> 1 con.executemany(insert_sql, data)
InterfaceError: Error binding parameter 0 - probably unsupported type.
A continuación se muestra el código que funcionó para mí. Pude escribirlo en SQLite DB.
import pandas as pd
import sqlite3 as sq
data = <This is going to be your pandas dataframe>
sql_data = ''D://SA.sqlite'' #- Creates DB names SQLite
conn = sq.connect(sql_data)
cur = conn.cursor()
cur.execute(''''''DROP TABLE IF EXISTS SA'''''')
data.to_sql(''SA'', conn, if_exists=''replace'', index=False) # - writes the pd.df to SQLIte DB
pd.read_sql(''select * from SentimentAnalysis'', conn)
conn.commit()
conn.close()
Como mencionó, en el momento en que guarda el índice, pero lo que podemos hacer es reset_index
, guardando el índice antiguo como una columna ( ''Date''
).
price2 = price.reset_index()
In [11]: price2
Out[11]:
<class ''pandas.core.frame.DataFrame''>
Int64Index: 1006 entries, 0 to 1005
Data columns:
Date 1006 non-null values
AAPL 1006 non-null values
GE 1006 non-null values
dtypes: datetime64[ns](1), float64(2)
Siguiendo los docs (configurando una conexión SQLite en memoria):
import sqlite3
from pandas.io import sql
# Create your connection.
cnx = sqlite3.connect('':memory:'')
Podemos ahorrar price2
a cnx
:
sql.write_frame(price2, name=''price2'', con=cnx)
Podemos recuperar a través de read_frame
:
p2 = sql.read_frame(''select * from price2'', cnx)
Sin embargo, cuando las fechas almacenadas (y recuperadas) son unicode
lugar de Timestamp
de Timestamp
. Para volver a convertir lo que comenzamos, podríamos apply
Timestamp
de Timestamp
a la columna y a set_index
:
from pandas.lib import Timestamp
p2.Date = p2.Date.apply(Timestamp)
p = p2.set_index(''Date'')
Recuperamos el mismo DataFrame que los prices
:
In [20]: p
Out[20]:
<class ''pandas.core.frame.DataFrame''>
DatetimeIndex: 1006 entries, 2009-01-02 00:00:00 to 2012-12-31 00:00:00
Data columns:
AAPL 1006 non-null values
GE 1006 non-null values
dtypes: float64(2)
Desafortunadamente, pandas.io.write_frame
ya no existe en las versiones más recientes de Pandas con respecto a la respuesta actual aceptada. Por ejemplo estoy usando pandas 0.19.2. Puedes hacer algo como
from sqlalchemy import create_engine
disk_engine = create_engine(''sqlite:///my_lite_store.db'')
price.to_sql(''stock_price'', disk_engine, if_exists=''append'')
Y luego a su vez previsualice su tabla con lo siguiente:
df = pd.read_sql_query(''SELECT * FROM stock_price LIMIT 3'',disk_engine)
df.head()