Mysql
 sql >> Database >  >> RDS >> Mysql

Il modo più veloce per caricare dati numerici in python/panda/numpy array da MySQL

Il "problema" sembra essere stato la conversione del tipo che si verifica dal tipo decimal di MySQL al decimal.Decimal di Python che MySQLdb, pymysql e pyodbc fanno sui dati. Modificando il file converters.py (nelle ultime righe) in MySQLdb per avere:

conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float

invece di decimal.Decimal sembra risolvere completamente il problema e ora il codice seguente:

import MySQLdb
import numpy
import time

t = time.time()
conn = MySQLdb.connect(host='',...)
curs = conn.cursor()
curs.execute("select x,y from TABLENAME")
data = numpy.array(curs.fetchall(),dtype=float)
print(time.time()-t)

Funziona in meno di un secondo! Che cosa è divertente, decimale. Il decimale non è mai sembrato essere il problema nel profiler.

Una soluzione simile dovrebbe funzionare nel pacchetto pymysql. pyodbc è più complicato:è tutto scritto in C++, quindi dovresti ricompilare l'intero pacchetto.

AGGIORNAMENTO

Ecco una soluzione che non richiede la modifica del codice sorgente di MySQLdb:Python MySQLdb restituisce datetime.date e decimale La soluzione quindi per caricare dati numerici nei panda:

import MySQLdb
import pandas.io.sql as psql
from MySQLdb.converters import conversions
from MySQLdb.constants import FIELD_TYPE

conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float
conn = MySQLdb.connect(host='',user='',passwd='',db='')
sql = "select * from NUMERICTABLE"
df = psql.read_frame(sql, conn)

Batte MATLAB di un fattore di ~4 nel caricamento di 200k x 9 tabelle!