Quel est le moyen le plus efficace pour convertir une base de données MySQL l'ensemble des résultats à un tableau NumPy?
Je suis en utilisant MySQLdb et Python. J'ai quelques requêtes de base comme ceci:
c=db.cursor()
c.execute("SELECT id, rating from video")
results = c.fetchall()
J'ai besoin de "résultats" à un tableau NumPy, et je suis à la recherche d'une solution économique avec ma consommation de mémoire. Il semble que de copier les données ligne par ligne serait incroyablement inefficace (le double de la mémoire). Est-il un meilleur moyen de convertir des MySQLdb les résultats de la requête dans le tableau NumPy format?
La raison pour laquelle je suis à la recherche d'utiliser le tableau NumPy format est parce que je veux être en mesure de trancher et couper en dés les données facilement, et il ne semble pas que python est très respectueux de matrices multi-dimensionnelles à cet égard.
e.g. b = a[a[:,2]==1]
Merci!
OriginalL'auteur thegreatt | 2011-08-15
Vous devez vous connecter pour publier un commentaire.
La
fetchall
méthode réellement retourne un itérateur, et numpy a la fromiter méthode pour initialiser un tableau à partir d'un interator. Ainsi, en fonction de ce que les données sont dans le tableau, vous pouvez combiner les deux facilement, ou utilisez un adaptateur générateur.Fromiter ne génère qu'un 1-d objet array bien, non? Dans cet exemple, nous aurions besoin d'un 2-d.. je suppose que tu peux le convertir en quelque sorte, mais dans ce cas, serait-ce toujours être la méthode la plus efficace?
Oui, vous pouvez remodeler par la suite.
Numpy les tableaux sont très efficace de cette façon. Vous pouvez définir les attributs de forme d'un tuple
(2,)
et cela devrait fonctionner.Salut Keith, merci pour cette info - heureux de savoir Numpy peut gérer ces gracieusement. Malheureusement, je suis aux prises avec le fromiter() fonction que vous recommandé..
results = c.fetchall()
D = np.fromiter(results, dtype=float, count=-1)
donneValueError: setting an array element with a sequence.
. Elle ne semble pas si les résultats est 1D ou 2D - des idées?OriginalL'auteur Keith
Cette solution utilise Kieth est fromiter technique, mais gère les deux dimensions de la table de la structure de SQL résultats de manière plus intuitive. Aussi, il améliore Doug méthode en évitant tous les remodeler et d'aplatissement en python les types de données. À l'aide d'un structuré tableau on peut lire assez bien directement à partir du résultat de MySQL dans numpy, le découpage de python les types de données presque entièrement. Je dis "presque" parce que le fetchall itérateur produit encore python tuples.
Il y a un problème, mais ce n'est pas un biggie. Vous devez connaître le type de données des colonnes et le nombre de lignes à l'avance.
Connaître les types de colonne devrait être évident, puisque vous savez ce que la requête est sans doute, sinon vous pouvez toujours utiliser les cabots.description, et une carte de la MySQLdb.TYPE_CHAMP.* les constantes.
Connaître le nombre de ligne signifie que vous devez utiliser curseur côté client (qui est la valeur par défaut). Je ne sais pas assez sur le fonctionnement interne de MySQLdb et la bibliothèque cliente MySQL, mais ma compréhension est que le résultat entier est récupérés dans le côté client de la mémoire lors de l'utilisation de curseurs côté client, bien que je soupçonne il y a effectivement certaines de mise en mémoire tampon et la mise en cache en cause. Cela signifie en utilisant le double de la mémoire pour le résultat, une fois le curseur de la copie et une fois pour le tableau de copie, donc c'est probablement une bonne idée de fermer le curseur dès que possible afin de libérer de la mémoire si le jeu de résultats est grande.
Strictement parlant, vous n'avez pas à fournir le nombre de lignes à l'avance, mais cela signifie que la matrice de la mémoire est allouée une fois éteint à l'avance, et pas en continu redimensionnée plus de lignes viennent de l'itérateur qui est destiné à fournir un énorme gain de performance.
Et avec ça, un peu de code
Voir le numpy documentation pour dtype et le lien ci-dessus sur les tableaux pour la façon de spécifier les types de données des colonnes, et les noms de colonne.
ndarray_data = A.view(np.int32).reshape((len(A),-1))
Substituer le meilleur type pour l'ensemble de vos données.OriginalL'auteur sirlark
NumPy est fromiter méthode semble la meilleure ici (comme dans de Keith réponse, qui a précédé celui-ci).
À l'aide de fromiter de refonte de l'ensemble des résultats, qui est retourné par un appel à une MySQLdb méthode de curseur, d'un tableau NumPy est simple, mais il ya un couple de détails peut-être la peine de mentionner.
Noter que fromiter renvoie une 1D tableau NumPY,
(Ce qui est logique, bien sûr, parce que vous pouvez utiliser fromiter pour revenir simplement une partie d'une seule Table MySQL ligne, en passant un paramètre pour compter).
Encore, vous aurez pour restaurer la forme 2D, d'où le prédicat appel à la méthode de curseur rowcount. et l'appel suivant à remodeler à la dernière ligne.
Enfin, l'argument par défaut pour le paramètre compter est '-1', qui récupère la totalité de l'objet iterable
c.execute("SELECT id, rating FROM video")
results = c.fetchall()
num_rows = int(c.rowcount)
D = np.fromiter(iterable=results, dtype=float, count=-1)
D = D.reshape(num_rows, -1)
édité ma Réponse à inclure les étapes intermédiaires de la refonte et de l'aplatissement de la "résultats". Pour enregistrer de frappe, je ne comprend pas ces trivial étapes dans ma réponse originale à cette question au lieu de cela tout en indiquant dans une ligne de commentaire qui "'résultat' il est imbriqué dans un tuple"
OriginalL'auteur doug