Het "probleem" lijkt de typeconversie te zijn geweest die plaatsvindt van het decimale type van MySQL naar het decimale type van python. Decimaal dat MySQLdb, pymysql en pyodbc doen op de gegevens. Door het converters.py-bestand (op de allerlaatste regels) in MySQLdb te wijzigen om:
conversions[FIELD_TYPE.DECIMAL] = float
conversions[FIELD_TYPE.NEWDECIMAL] = float
in plaats van decimaal.Decimaal lijkt het probleem volledig op te lossen en nu de volgende code:
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)
Loopt in minder dan een seconde! Wat grappig is, decimaal. Decimaal leek nooit het probleem te zijn in de profiler.
Een vergelijkbare oplossing zou moeten werken in het pymysql-pakket. pyodbc is lastiger:het is allemaal geschreven in C++, dus je zou het hele pakket opnieuw moeten compileren.
UPDATE
Hier is een oplossing waarvoor u de MySQLdb-broncode niet hoeft te wijzigen:Python MySQLdb geeft datetime.date en decimaal terug De oplossing om vervolgens numerieke gegevens in panda's te laden:
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)
Verslaat MATLAB met een factor ~4 bij het laden van een tafel van 200k x 9!