У меня есть серия из списков

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

И я хочу DataFrame с каждым столбцом списка.

Ни один из from_items, from_records, DataFrame Series.to_frame не работает.

Как это сделать?

15
Hatshepsut 27 Авг 2017 в 04:36

7 ответов

Лучший ответ

Вы можете использовать from_items следующим образом (при условии, что ваши списки имеют одинаковую длину):

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

   0  1
0  1  4
1  2  5
2  3  6

Или

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

   0  1  2
0  1  2  3
1  4  5  6

В зависимости от желаемого результата.

Это может быть намного быстрее, чем использование apply (как используется в @ ответе Вена, который, однако, также работа для списков разной длины):

%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

А также

%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

Также @ Ответ Хатшепсута довольно быстрый (также работает для списков разной длины):

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

А также

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

Кажется, самым быстрым решением является @ ответ Abdou (протестировано для Python 2; также работает для списков различной длины; используйте {{X0 }} в Python 3.6+):

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

Дополнительная опция:

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

   0  1
0  1  4
1  2  5
2  3  6
15
John 20 Ноя 2017 в 19:38

pd.DataFrame.from_records также должен работать с использованием 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
5
Abdou 27 Авг 2017 в 02:35

Переберите серию так:

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
3
Hatshepsut 27 Авг 2017 в 01:43

Вы можете искать

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

Или же

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

Out[133]: 
   0  1
0  1  4
1  2  5
2  3  6
2
YOBEN_S 27 Авг 2017 в 01:41

Обратите внимание , что метод from_items() в принятом ответе устарел в последних версиях Pandas, и вместо него следует использовать метод from_dict(). Вот как:

pd.DataFrame.from_dict(dict(zip(s.index, s.values)))

## OR  

pd.DataFrame.from_dict(dict(zip(s.index, s.values))).T

Также обратите внимание, что использование from_dict() дает нам подход самый быстрый на данный момент:

%timeit pd.DataFrame.from_dict(dict(zip(s.index, s.values)))
376 µs ± 14.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

## OR

%timeit pd.DataFrame.from_dict(dict(zip(s.index, s.values))).T
487 µs ± 3.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1
Dataman 4 Июн 2019 в 08:11

Пытаться:

import numpy as np, pandas as pd
s = pd.Series([[1, 2, 3], [4, 5, 6]])
pd.DataFrame(np.vstack(s))
0
Evan Rosica 13 Янв 2020 в 07:28

Если длина серии очень велика (более 1 м), вы можете использовать:

s = pd.Series([[1, 2, 3], [4, 5, 6]])
pd.DataFrame(s.tolist())
2
Z.Webber 30 Окт 2017 в 16:26