Cette réponse n'apporte pas de réponses qui ne soient pas déjà discutées, mais voici quelques résultats de vitesse. Je pense que cela devrait résoudre les questions qui sont apparues dans les commentaires. Tous ces résultats semblent être O(n) sur la base de ces trois valeurs.
TL;DR : tuples = list(df.itertuples(index=False, name=None))
et tuples = list(zip(*[df[c].values.tolist() for c in df]))
sont à égalité pour le plus rapide.
J'ai fait un rapide test de vitesse sur les résultats de trois suggestions ici :
- La réponse zip de @pirsquared :
tuples = list(zip(*[df[c].values.tolist() for c in df]))
- La réponse acceptée de @wes-mckinney :
tuples = [tuple(x) for x in df.values]
-
La réponse itertuples de @ksindi avec les name=None
suggestion de @Axel : tuples = list(df.itertuples(index=False, name=None))
from numpy import random
import pandas as pd
def create_random_df(n):
return pd.DataFrame({"A": random.randint(n, size=n), "B": random.randint(n, size=n)})
Petite taille :
df = create_random_df(10000)
%timeit tuples = list(zip(*[df[c].values.tolist() for c in df]))
%timeit tuples = [tuple(x) for x in df.values]
%timeit tuples = list(df.itertuples(index=False, name=None))
Donne :
1.66 ms ± 200 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
15.5 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
1.74 ms ± 75.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Plus grand :
df = create_random_df(1000000)
%timeit tuples = list(zip(*[df[c].values.tolist() for c in df]))
%timeit tuples = [tuple(x) for x in df.values]
%timeit tuples = list(df.itertuples(index=False, name=None))
Donne :
202 ms ± 5.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
1.52 s ± 98.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
209 ms ± 11.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Autant de patience que j'ai :
df = create_random_df(10000000)
%timeit tuples = list(zip(*[df[c].values.tolist() for c in df]))
%timeit tuples = [tuple(x) for x in df.values]
%timeit tuples = list(df.itertuples(index=False, name=None))
Donne :
1.78 s ± 118 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
15.4 s ± 222 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1.68 s ± 96.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
La version zip et la version itertuples sont dans les intervalles de confiance l'une de l'autre. Je soupçonne qu'elles font la même chose sous le capot.
Ces tests de vitesse ne sont probablement pas pertinents. Pousser les limites de la mémoire de mon ordinateur ne prend pas énormément de temps, et vous vraiment ne devrait pas faire ça 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 qu'il s'agisse d'un goulot d'étranglement majeur dans votre code, alors contentez-vous de la version qui vous semble la plus lisible.
36 votes
Pour ceux qui viennent à cette réponse en 2017+, il y a une nouvelle solution idiomatique ci-dessous . Vous pouvez simplement utiliser
list(df.itertuples(index=False, name=None))
5 votes
Les deux choses que je recherche lorsque je me pose cette question : Une liste de tuples -
df.to_records(index=False)
et une liste de dicts :df.to_dict('records')
1 votes
@MartinThoma Les deux to_records et to_dict('records') bousillent mes types de données. Bug connu mais qui rend cette solution inutile...