it-swarm.com.de

So schreiben Sie Pandas-Datenrahmen mit Index in SQLite

Ich habe eine Liste von Börsendaten, die von Yahoo in einem Pandas-DataFrame abgerufen wurden (siehe Format unten). Das Datum dient als Index im DataFrame. Ich möchte die Daten (einschließlich des Index) in eine SQLite-Datenbank schreiben.

             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

Aufgrund meines Lesens des write_frame-Codes für Pandas unterstützt es derzeit nicht das Schreiben des Index . Ich habe versucht, stattdessen to_records zu verwenden, bin jedoch auf das Problem mit Numpy 1.6.2 und datetimes gestoßen. Jetzt versuche ich, Tupel mit .itertuples zu schreiben, aber SQLite gibt eine Fehlermeldung aus, dass der Datentyp nicht unterstützt wird (siehe Code und Ergebnis unten). Ich bin relativ neu in Python, Pandas und Numpy, daher ist es durchaus möglich, dass mir etwas Offensichtliches fehlt. Ich glaube, ich habe ein Problem beim Versuch, eine Datums- und Uhrzeitangabe in SQLite zu schreiben, aber ich denke, dies könnte zu kompliziert werden.

Ich glaube, ich kann das Problem beheben, indem ich auf Numpy 1.7 oder die auf GitHub veröffentlichte Entwicklungsversion von Pandas aktualisiere. Ich würde es vorziehen, mit Release-Versionen von Software zu entwickeln - ich bin neu in diesem Bereich und möchte nicht, dass Stabilitätsprobleme die Sache weiter verwirren.

Gibt es eine Möglichkeit, dies mit Python 2.7.2, Pandas 0.10.0 und Numpy 1.6.2 zu erreichen? Vielleicht die Daten mal irgendwie bereinigen? Ich bin etwas überfordert, jede Hilfe wäre willkommen.

Code:

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)

Ergebnis:

---------------------------------------------------------------------------
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.
22
jmatthewhouse

Bei den jüngsten Pandas wird der Index in der Datenbank gespeichert (vorher mussten Sie zuerst reset_index ).

Nach dem docs (Einrichten einer SQLite-Verbindung im Arbeitsspeicher):

import sqlite3
# Create your connection.
cnx = sqlite3.connect(':memory:')

Hinweis: Sie können hier auch eine SQLAlchemy-Engine übergeben (siehe Antwortende).

Wir können price2 in cnx speichern:

price2.to_sql(name='price2', con=cnx)

Wir können über read_sql abrufen:

p2 = pd.read_sql('select * from price2', cnx)

Beim Speichern (und Abrufen) sind Datumsangaben jedoch unicode und nicht Timestamp. Um wieder zu dem zurückzukehren, was wir begonnen haben, können wir pd.to_datetime verwenden:

p2.Date = pd.to_datetime(p2.Date)
p = p2.set_index('Date')

Wir erhalten denselben DataFrame als prices zurück:

In [11]: p2
Out[11]: 
<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)

Sie können auch eine SQLAlchemy-Engine verwenden:

from sqlalchemy import create_engine
e = create_engine('sqlite://')  # pass your db url

price2.to_sql(name='price2', con=cnx)

Dies ermöglicht Ihnen die Verwendung von read_sql_table (die nur mit SQLAlchemy verwendet werden kann):

pd.read_sql_table(table_name='price2', con=e)
#         Date   AAPL     GE
# 0 2009-01-02  89.95  14.76
# 1 2009-01-05  93.75  14.38
# 2 2009-01-06  92.20  14.58
# 3 2009-01-07  90.21  13.93
# 4 2009-01-08  91.88  13.95
27
Andy Hayden

Leider existiert pandas.io.write_frame nicht mehr in neueren Pandas-Versionen in Bezug auf die aktuell akzeptierte Antwort. Zum Beispiel verwende ich Pandas 0.19.2. Sie können so etwas tun 

from sqlalchemy import create_engine

disk_engine = create_engine('sqlite:///my_lite_store.db')
price.to_sql('stock_price', disk_engine, if_exists='append')

Anschließend können Sie eine Vorschau Ihrer Tabelle mit den folgenden Optionen anzeigen:

df = pd.read_sql_query('SELECT * FROM stock_price LIMIT 3',disk_engine)
df.head()
10
Wes

Unten ist der Code, der für mich funktioniert hat. Ich konnte es in SQLite DB schreiben.

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()
1
Keerthesh Kumar