J'ai manipulé certaines données à l'aide de pandas et je souhaite maintenant effectuer une sauvegarde par lots dans la base de données. Cela m'oblige à convertir le dataframe en un tableau de tuples, chaque tuple correspondant à une "ligne" du dataframe.
Mon DataFrame ressemble à quelque chose comme:
In [182]: data_set
Out[182]:
index data_date data_1 data_2
0 14303 2012-02-17 24.75 25.03
1 12009 2012-02-16 25.00 25.07
2 11830 2012-02-15 24.99 25.15
3 6274 2012-02-14 24.68 25.05
4 2302 2012-02-13 24.62 24.77
5 14085 2012-02-10 24.38 24.61
Je veux le convertir en un tableau de tuples comme:
[(datetime.date(2012,2,17),24.75,25.03),
(datetime.date(2012,2,16),25.00,25.07),
...etc. ]
Une suggestion sur la façon dont je peux le faire efficacement?
list(df.itertuples(index=False, name=None))
df.to_records(index=False)
et une liste de dictionnaires:df.to_dict('records')
Réponses:
Que diriez-vous:
pour les pandas <0,24 utilisation
la source
.itertuples
, ce qui sera plus efficace que d'obtenir les valeurs sous forme de tableau et de les transformer en un tuple.À partir de 17.1, ce qui précède renverra une liste de tuples nommés .
Si vous voulez une liste de tuples ordinaires, passez
name=None
en argument:la source
tuple
s normaux dans votrezip
itérateur (au lieu denamedtuple
s), appelez:data_set.itertuples(index=False, name=None)
itertuples
est lent . Évitez si possible. Pour les boucles (comme indiqué, la réponse acceptée) est généralement plus rapide dans ces cas.Une manière générique:
la source
data_set.to_records(index=False).tolist()
mieux?Motivation
De nombreux ensembles de données sont suffisamment volumineux pour que nous nous préoccupions de la vitesse / efficacité. Je propose donc cette solution dans cet esprit. Il se trouve que c'est aussi succinct.
Par souci de comparaison, supprimons la
index
colonneSolution
Je proposerai l'utilisation de
zip
etmap
Il se trouve être également flexible si nous voulions traiter un sous-ensemble spécifique de colonnes. Nous supposerons que les colonnes que nous avons déjà affichées sont le sous-ensemble que nous voulons.
Qu'est-ce qui est plus rapide?
Turn's out
records
est le plus rapide suivi d'une convergence asymptotiquezipmap
etiter_tuples
J'utiliserai une bibliothèque
simple_benchmarks
que j'ai obtenue de ce postVérifiez les résultats
la source
Voici une approche vectorisée (en supposant le dataframe,
data_set
à définir comme à ladf
place) qui retourne alist
oftuples
comme indiqué:produit:
L'idée de définir la colonne datetime comme axe d'index est d'aider à la conversion de la
Timestamp
valeur en sondatetime.datetime
équivalent de format correspondant en utilisant l'convert_datetime64
argument dansDF.to_records
lequel le fait pour unDateTimeIndex
dataframe.Cela renvoie un
recarray
qui pourrait alors être fait pour retourner un enlist
utilisant.tolist
Une solution plus généralisée selon le cas d'utilisation serait:
la source
Le moyen le plus efficace et le plus simple:
Vous pouvez filtrer les colonnes dont vous avez besoin avant cet appel.
la source
Cette réponse n'ajoute aucune réponse qui ne soit pas déjà discutée, mais voici quelques résultats rapides. Je pense que cela devrait résoudre les questions soulevées dans les commentaires. Tous ces éléments semblent être O (n) , sur la base de ces trois valeurs.
TL; DR :
tuples = list(df.itertuples(index=False, name=None))
ettuples = list(zip(*[df[c].values.tolist() for c in df]))
sont à égalité pour les plus rapides.J'ai fait un test de vitesse rapide sur les résultats pour trois suggestions ici:
tuples = list(zip(*[df[c].values.tolist() for c in df]))
tuples = [tuple(x) for x in df.values]
name=None
suggestion de @Axel:tuples = list(df.itertuples(index=False, name=None))
Petite taille:
Donne:
Plus grand:
Donne:
Autant de patience que moi:
Donne:
La version zip et la version itertuples sont dans les intervalles de confiance l'une de l'autre. Je soupçonne qu'ils font la même chose sous le capot.
Ces tests de vitesse ne sont probablement pas pertinents. Repousser les limites de la mémoire de mon ordinateur ne prend pas beaucoup de temps, et vous ne devriez vraiment pas faire cela sur un grand ensemble de données. Travailler avec ces tuples après avoir fait cela finira par être vraiment inefficace. Il est peu probable que ce soit un goulot d'étranglement majeur dans votre code, alors tenez-vous-en à la version que vous pensez la plus lisible.
la source
[*zip(*map(df.get, df))]
temps maintenant. Quoi qu'il en soit, j'ai pensé que tu trouverais ça intéressant.la source
Changement de la liste des cadres de données en une liste de tuples.
la source
Plus de manière pythonique:
la source
map()
est notoirement impythonique.