web-dev-qa-db-fra.com

Convertir une série de listes de pandas en dataframe

J'ai une série de listes

import pandas as pd
s = pd.Series([[1, 2, 3], [4, 5, 6]])

et je veux un DataFrame avec chaque colonne une liste. 

Aucun de from_items, from_records, DataFrameSeries.to_frame ne semble fonctionner. 

Comment faire ça?

6
Hatshepsut

Vous pouvez utiliser from_items comme ceci (en supposant que vos listes ont la même longueur):

pd.DataFrame.from_items(Zip(s.index, s.values))

   0  1
0  1  4
1  2  5
2  3  6

ou

pd.DataFrame.from_items(Zip(s.index, s.values)).T

   0  1  2
0  1  2  3
1  4  5  6

en fonction de votre sortie désirée.

Cela peut être beaucoup plus rapide que d'utiliser une variable apply (telle qu'elle est utilisée dans la réponse de @ Wen , qui fonctionne également pour des listes de longueur différente):

%timeit pd.DataFrame.from_items(Zip(s.index, s.values))
1000 loops, best of 3: 669 µs per loop

%timeit s.apply(lambda x:pd.Series(x)).T
1000 loops, best of 3: 1.37 ms per loop

et

%timeit pd.DataFrame.from_items(Zip(s.index, s.values)).T
1000 loops, best of 3: 919 µs per loop

%timeit s.apply(lambda x:pd.Series(x))
1000 loops, best of 3: 1.26 ms per loop

De plus, la réponse de @ Hatshepsut est assez rapide (fonctionne également pour des listes de longueurs différentes):

%timeit pd.DataFrame(item for item in s)
1000 loops, best of 3: 636 µs per loop

et 

%timeit pd.DataFrame(item for item in s).T
1000 loops, best of 3: 884 µs per loop

La solution la plus rapide semble être la réponse de @ Abdou (testé pour Python 2; fonctionne également pour des listes de longueur différente; utilisez itertools.Zip_longest dans Python 3.6+):

%timeit pd.DataFrame.from_records(izip_longest(*s.values))
1000 loops, best of 3: 529 µs per loop

Une option supplémentaire:

pd.DataFrame(dict(Zip(s.index, s.values)))

   0  1
0  1  4
1  2  5
2  3  6
12
Cleb

pd.DataFrame.from_records devrait également fonctionner avec itertools.Zip_longest :

from itertools import Zip_longest

pd.DataFrame.from_records(Zip_longest(*s.values))

#    0  1
# 0  1  4
# 1  2  5
# 2  3  6
4
Abdou

Si la longueur de la série est très haute (plus de 1 m), vous pouvez utiliser:

s = pd.Series([[1, 2, 3], [4, 5, 6]])
pd.DataFrame(s.tolist())
1
Z.Webber

Vous pouvez chercher 

s.apply(lambda x:pd.Series(x))
   0  1  2
0  1  2  3
1  4  5  6

Ou 

 s.apply(lambda x:pd.Series(x)).T

Out[133]: 
   0  1
0  1  4
1  2  5
2  3  6
1
Wen-Ben

Itérer sur la série comme ceci:

series = pd.Series([[1, 2, 3], [4, 5, 6]])
pd.DataFrame(item for item in series)

   0  1  2
0  1  2  3
1  4  5  6
1
Hatshepsut