2016-02-24 34 views
5

vorrei convertire un'interrogazione psycopg2 DictRow ad un dataframe panda, ma panda continua a lamentarsi:Converti psycopg2 interrogazione DictRow per Pandas dataframe

curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) 
curs.execute("SELECT * FROM mytable") 
data = curs.fetchall() 

print type(data) 
print pd.DataFrame(list(data)) 

Tuttavia, ho sempre arrivare un errore anche se ho passato un particolare list ?? ?

<type 'list'> 
TypeError: Expected list, got DictRow 

Il risultato è lo stesso se io pd.DataFrame(data) Qualcuno potrebbe aiutarmi a fare questo lavoro?

Sarebbe anche bello se i nomi delle colonne del dataframe funzionassero (ad esempio estrarre DictRow e passarli al dataframe).

Aggiornamento:
Da quando ho bisogno di elaborare i dati, vorrei utilizzare i dati dalla query psycopg2 come è e non il pandas approach, per esempio read_sql_query.

+0

Aperto un problema su GitHub: https://github.com/pydata/pandas/issues/14169 – n1000

risposta

5

Hmm, alla fine ho trovato questa soluzione hacky:

print pd.DataFrame([i.copy() for i in data]) 

La copy() funzione della classe DictRow restituirà un dizionario vero e proprio. Con la comprensione delle liste creo una lista di dizionari (identici), che i panda accetteranno felicemente.

Sono ancora perplesso sul motivo per cui list(data) ha prodotto un TypeError. Forse qualcuno può ancora illuminarmi.

3

AGGIORNAMENTO: pandas.read_sql_query() è un modo più elegante per leggere una query SQL in un dataframe, senza la necessità di psycopg2. Vedi lo pandas docs.

Ho avuto lo stesso problema. Il modo più semplice che ho trovato è stato convertire DictRow in un array numpy.

import numpy as np 
curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) 
curs.execute("SELECT * FROM mytable") 
data = curs.fetchall() 

print type(data) 
print pd.DataFrame(np.array(data)) 

Se si desidera ottenere i nomi delle colonne, è possibile accedervi come chiavi per ogni riga della DictRow. Tuttavia, la conversione in una matrice numpy non mantiene l'ordine. Quindi uno (inelegante) modo è il seguente:

curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor) 
curs.execute("SELECT * FROM mytable") 
data = curs.fetchall() 

print type(data) 
colNames = data[0].keys() 
print pd.DataFrame([[row[col] for col in colNames] for row in data], columns=colNames)