Motivation
De nombreux ensembles de données sont suffisamment volumineux pour que nous devions nous préoccuper de la vitesse et de l'efficacité. C'est dans cet esprit que je propose cette solution. Il se trouve qu'elle est également succincte.
Pour les besoins de la comparaison, laissons tomber l'élément index
colonne
df = data_set.drop('index', 1)
Solution
Je vais proposer l'utilisation de zip
et map
list(zip(*map(df.get, df)))
[('2012-02-17', 24.75, 25.03),
('2012-02-16', 25.0, 25.07),
('2012-02-15', 24.99, 25.15),
('2012-02-14', 24.68, 25.05),
('2012-02-13', 24.62, 24.77),
('2012-02-10', 24.38, 24.61)]
Il se trouve qu'elle est également flexible si nous voulons 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.
list(zip(*map(df.get, ['data_date', 'data_1', 'data_2'])))
[('2012-02-17', 24.75, 25.03),
('2012-02-16', 25.0, 25.07),
('2012-02-15', 24.99, 25.15),
('2012-02-14', 24.68, 25.05),
('2012-02-13', 24.62, 24.77),
('2012-02-10', 24.38, 24.61)]
Qu'est-ce qui est plus rapide ?
C'est fini. records
est le plus rapide, suivi d'une convergence asymptotique. zipmap
et iter_tuples
Je vais utiliser une bibliothèque simple_benchmarks
que j'ai obtenu de ce poste
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
import pandas as pd
import numpy as np
def tuple_comp(df): return [tuple(x) for x in df.to_numpy()]
def iter_namedtuples(df): return list(df.itertuples(index=False))
def iter_tuples(df): return list(df.itertuples(index=False, name=None))
def records(df): return df.to_records(index=False).tolist()
def zipmap(df): return list(zip(*map(df.get, df)))
funcs = [tuple_comp, iter_namedtuples, iter_tuples, records, zipmap]
for func in funcs:
b.add_function()(func)
def creator(n):
return pd.DataFrame({"A": random.randint(n, size=n), "B": random.randint(n, size=n)})
@b.add_arguments('Rows in DataFrame')
def argument_provider():
for n in (10 ** (np.arange(4, 11) / 2)).astype(int):
yield n, creator(n)
r = b.run()
Vérifiez les résultats
r.to_pandas_dataframe().pipe(lambda d: d.div(d.min(1), 0))
tuple_comp iter_namedtuples iter_tuples records zipmap
100 2.905662 6.626308 3.450741 1.469471 1.000000
316 4.612692 4.814433 2.375874 1.096352 1.000000
1000 6.513121 4.106426 1.958293 1.000000 1.316303
3162 8.446138 4.082161 1.808339 1.000000 1.533605
10000 8.424483 3.621461 1.651831 1.000000 1.558592
31622 7.813803 3.386592 1.586483 1.000000 1.515478
100000 7.050572 3.162426 1.499977 1.000000 1.480131
r.plot()
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...