Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Maneira mais rápida de carregar dados numéricos no array python/pandas/numpy do MySQL


O "problema" parece ter sido a conversão de tipo que ocorre do tipo decimal do MySQL para o decimal do python.Decimal que MySQLdb, pymysql e pyodbc fazem nos dados. Alterando o arquivo converters.py (nas últimas linhas) no MySQLdb para ter:
conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float

em vez de decimal.Decimal parece resolver completamente o problema e agora o seguinte código:
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)

Funciona em menos de um segundo! O que é engraçado, decimal.Decimal nunca pareceu ser o problema no profiler.

Solução semelhante deve funcionar no pacote pymysql. pyodbc é mais complicado:é tudo escrito em C++, portanto, você teria que recompilar o pacote inteiro.

ATUALIZAÇÃO

Aqui está uma solução que não requer a modificação do código-fonte MySQLdb:Python MySQLdb retorna datetime.date e decimal A solução então para carregar dados numéricos em pandas:
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)

Supera o MATLAB por um fator de ~4 no carregamento de uma mesa de 200k x 9!