Получить список из заголовков столбцов DataFrame от pandas


1017

Я хочу получить список заголовков столбцов в панде DataFrame. DataFrame будет поступать от пользователя, поэтому я не буду знать, сколько будет столбцов или как они будут называться.

Например, если мне дан DataFrame, как это:

>>> my_dataframe
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

Я хотел бы получить список как это:

>>> header_list
['y', 'gdp', 'cap']

С python3.5 + вы можете использовать [*df]более list(df)или df.columns.tolist(), это благодаря распаковке обобщений (PEP 448) .
cs95

Ответы:


1649

Вы можете получить значения в виде списка, выполнив:

list(my_dataframe.columns.values)

Также вы можете просто использовать: (как показано в ответе Эда Чума ):

list(my_dataframe)

42
Почему этот документ не имеет columnsатрибута?
Tjorriemorrie

@Tjorriemorrie: Я не уверен, возможно, это связано с тем, как они автоматически генерируют свою документацию. Это упоминается в других местах, хотя: pandas.pydata.org/pandas-docs/stable/…
Симеон Виссер

8
Я бы ожидал что-то подобное df.column_names(). Правильно ли этот ответ или он устарел?
Alvas

1
@alvas Существуют и другие способы сделать это (см. другие ответы на этой странице), но, насколько я знаю, на фрейме данных нет метода для непосредственного создания списка.
Симеон Виссер

19
Важно отметить, что это сохраняет порядок столбцов.
WindChimes

405

Существует встроенный метод, который наиболее эффективен:

my_dataframe.columns.values.tolist()

.columnsвозвращает индекс, .columns.valuesвозвращает массив и имеет вспомогательную функцию .tolistдля возврата списка.

Если производительность не так важна для вас, Indexобъекты определяют .tolist()метод, который вы можете вызвать напрямую:

my_dataframe.columns.tolist()

Разница в производительности очевидна:

%timeit df.columns.tolist()
16.7 µs ± 317 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit df.columns.values.tolist()
1.24 µs ± 12.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Для тех , кто ненавидит печатать, вы можете просто позвонить listпо df, как это:

list(df)

4
Не отказывался от голосования, но хочу объяснить: не полагайтесь на детали реализации, используйте «открытый интерфейс» DataFrame. Подумайте о красоте df.keys ()
Саша Готфрид

3
@SaschaGottfried Реализация DataFrameитерируемого не изменилась с первого дня: pandas.pydata.org/pandas-docs/stable/basics.html#iteration . Итерируемое значение, возвращаемое из DataFrame, всегда было столбцами, поэтому выполнение for col in df:всегда должно вести себя одинаково, если разработчики не потерпели крах list(df)и не должны оставаться допустимым методом. Обратите внимание, что df.keys()вызов внутренней реализации dict-like структуры возвращает ключи, являющиеся столбцами. Необъяснимое понижение - это побочный ущерб, который стоит ожидать от SO, так что не волнуйтесь
EdChum

Я ссылался на детали реализации columnsатрибута. Час назад я прочитал о Законе Деметры, пропагандирующем, что вызывающий объект не должен зависеть от навигации по внутренней объектной модели. list(df)делает явное преобразование типов. Заметный побочный эффект: увеличение времени выполнения и потребления памяти с помощью df.keys()метода размера данных является частью dict-подобной природы a DataFrame. Примечательный факт: время выполнения для df.keys()довольно постоянное независимо от размера фрейма данных - часть ответственности разработчиков панд.
Саша Готфрид

1
@SaschaGottfried Я могу добавить это к своему ответу и отметить, что вы видите, как никто другой не включил это
EdChum

1
Я вижу ценность в данном ответе, а также в комментариях - не нужно ничего менять.
Саша Готфрид

89

Провел несколько быстрых тестов, и, возможно, неудивительно, что встроенная версия, используемая dataframe.columns.values.tolist()быстрее всего:

In [1]: %timeit [column for column in df]
1000 loops, best of 3: 81.6 µs per loop

In [2]: %timeit df.columns.values.tolist()
10000 loops, best of 3: 16.1 µs per loop

In [3]: %timeit list(df)
10000 loops, best of 3: 44.9 µs per loop

In [4]: % timeit list(df.columns.values)
10000 loops, best of 3: 38.4 µs per loop

(Мне все еще очень нравится это list(dataframe), так что спасибо EdChum!)


47

Это становится еще проще (панды 0.16.0):

df.columns.tolist()

даст вам имена столбцов в хорошем списке.


37
>>> list(my_dataframe)
['y', 'gdp', 'cap']

Чтобы вывести список столбцов данных в режиме отладчика, используйте понимание списка:

>>> [c for c in my_dataframe]
['y', 'gdp', 'cap']

Кстати, вы можете получить отсортированный список просто используя sorted:

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']

Будет ли это list(df)работать только с автокадрами данных? Или это работает для всех фреймов данных?
Alvas

2
Должно работать для всех. Однако, когда вы находитесь в отладчике, вам нужно использовать понимание списка [c for c in df].
Александр

25

Удивлен, я еще не видел это опубликовано, поэтому я просто оставлю это здесь.

Расширенная повторяемая распаковка (python3.5 +): [*df]и друзья

Обобщения распаковки (PEP 448) были введены в Python 3.5. Итак, следующие операции все возможны.

df = pd.DataFrame('x', columns=['A', 'B', 'C'], index=range(5))
df

   A  B  C
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x 

Если вы хотите list....

[*df]
# ['A', 'B', 'C']

Или, если вы хотите set,

{*df}
# {'A', 'B', 'C'}

Или, если вы хотите tuple,

*df,  # Please note the trailing comma
# ('A', 'B', 'C')

Или, если вы хотите сохранить результат где-то,

*cols, = df  # A wild comma appears, again
cols
# ['A', 'B', 'C']

... если вы тот человек, который превращает кофе в печатание звуков, ну, это будет потреблять ваш кофе более эффективно;)

PS: если важна производительность, вам нужно отказаться от вышеупомянутых решений в пользу

df.columns.to_numpy().tolist()
# ['A', 'B', 'C']

Это похоже на ответ Эда Чума , но обновлено для v0.24, где .to_numpy()предпочтительнее использования .values. Смотрите этот ответ (мной) для получения дополнительной информации.

Визуальная проверка
Поскольку я видел это в других ответах, вы можете использовать итеративную распаковку (нет необходимости в явных циклах).

print(*df)
A B C

print(*df, sep='\n')
A
B
C

Критика других методов

Не используйте явный forцикл для операции, которая может быть сделана в одной строке (списки в порядке).

Далее, использование sorted(df) не сохраняет первоначальный порядок столбцов. Для этого вы должны использовать list(df)вместо этого.

Далее, list(df.columns)и list(df.columns.values)плохие предложения (по состоянию на текущую версию, v0.24). Оба Index(возвращено из df.columns) и массивы NumPy (возвращено df.columns.values) определяют .tolist()метод, который быстрее и более идиоматичен.

Наконец, listification, т. Е. list(df)Должен использоваться только в качестве краткой альтернативы вышеупомянутым методам для python <= 3.4, где расширенная распаковка недоступна.


24

Это доступно как my_dataframe.columns.


1
И явно в виде спискаheader_list = list(my_dataframe.columns)
yeliabsalohcin

^ Или еще лучше: df.columns.tolist().
cs95

18

Это интересно, но df.columns.values.tolist()почти в 3 раза быстрее, df.columns.tolist()но я подумал, что они одинаковые:

In [97]: %timeit df.columns.values.tolist()
100000 loops, best of 3: 2.97 µs per loop

In [98]: %timeit df.columns.tolist()
10000 loops, best of 3: 9.67 µs per loop

2
Сроки уже были рассмотрены в этом ответе . Причина расхождения заключается в том, что .valuesвозвращает базовый массив NumPy, и выполнение чего-либо с помощью NUMPY почти всегда происходит быстрее, чем выполнение того же самого с пандами напрямую.
cs95

17

DataFrame следует Dict-как конвенция итерации «ключи» объекты.

my_dataframe.keys()

Создать список ключей / столбцов - метод объекта to_list()и питонический способ

my_dataframe.keys().to_list()
list(my_dataframe.keys())

Базовая итерация в DataFrame возвращает метки столбцов

[column for column in my_dataframe]

Не конвертируйте DataFrame в список, просто чтобы получить метки столбцов. Не переставайте думать, ища удобные примеры кода.

xlarge = pd.DataFrame(np.arange(100000000).reshape(10000,10000))
list(xlarge) #compute time and memory consumption depend on dataframe size - O(N)
list(xlarge.keys()) #constant time operation - O(1)

2
Мои тесты показывают df.columnsнамного быстрее, чем df.keys(). Не уверен, почему у них есть и функция, и атрибут для одной и той же вещи (ну, я не первый раз видел 10 разных способов сделать что-то в пандах).
cs95

1
Цель моего ответа состояла в том, чтобы показать несколько способов запроса меток столбцов из DataFrame и выделить анти-шаблон производительности. Тем не менее, мне нравятся ваши комментарии и голосование за ваш недавний ответ - поскольку они представляют ценность с точки зрения разработки программного обеспечения.
Саша Готфрид

14

В тетради

Для исследования данных в записной книжке IPython мой предпочтительный способ заключается в следующем:

sorted(df)

Который будет производить легко читаемый в алфавитном порядке список.

В репозитории кода

В коде я нахожу это более явным

df.columns

Потому что он говорит другим, читающим ваш код, что вы делаете.


sorted(df)меняет порядок. Используйте с осторожностью.
cs95

@coldspeed Я упоминаю об этом, хотя "который даст легко читаемый список в алфавитном порядке".
firelynx

9
%%timeit
final_df.columns.values.tolist()
948 ns ± 19.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
list(final_df.columns)
14.2 µs ± 79.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(final_df.columns.values)
1.88 µs ± 11.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%%timeit
final_df.columns.tolist()
12.3 µs ± 27.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
list(final_df.head(1).columns)
163 µs ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

3

как ответил Симеон Виссер ... вы могли бы сделать

list(my_dataframe.columns.values) 

или

list(my_dataframe) # for less typing.

Но я думаю, что самое приятное место это:

list(my_dataframe.columns)

Это явно, в то же время не излишне долго.


«Это явно, в то же время не излишне долго». Я не согласен. Вызов не listимеет смысла, если вы не вызываете его dfнапрямую (например, для краткости). Доступ к .columnsатрибуту возвращает Indexобъект, для которого tolist()определен метод, и вызов которого более идиоматичен, чем прослушивание Index. Смешивать идиомы только ради полноты - не лучшая идея. То же самое относится и к списку массивов, из которых вы получаете .values.
cs95


3

Это дает нам имена столбцов в списке:

list(my_dataframe.columns)

Также можно использовать другую функцию с именем tolist ():

my_dataframe.columns.tolist()

Об этом уже говорилось в других ответах. Ваше первое решение также смешивает идиомы, что не очень хорошая идея. Смотрите мой комментарий под другим ответом.
cs95

2

Мне кажется, вопрос заслуживает дополнительного объяснения.

Как заметил @fixxxer, ответ зависит от версии панд, которую вы используете в своем проекте. Который вы можете получить с помощью pd.__version__команды.

Если вы по какой-то причине, как я (в Debian Jessie, я использую 0.14.1), используете более старую версию панд, чем 0.16.0, тогда вам нужно использовать:

df.keys().tolist()потому что df.columnsметод еще не реализован.

Преимущество этого метода ключей в том, что он работает даже в более новых версиях панд, поэтому он более универсален.


Недостаток keys () в том, что это вызов функции, а не поиск атрибута, поэтому он всегда будет медленнее. Конечно, при постоянном доступе никого не волнуют подобные различия, но я думаю, что все равно стоит упомянуть; df.columns теперь является более общепринятой идиомой для доступа к заголовкам.
cs95

1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n

6
пожалуйста, замените его на понимание списка.
Саша Готфрид

4
измените свои первые 3 строки на[n for n in dataframe.columns]
Антон Протопопов

Почему вы хотите пройти через все эти неприятности для операции, которую вы можете легко выполнить в одной строке?
cs95

0

Хотя решение, которое было предоставлено выше, приятно. Я также ожидал бы, что что-то вроде frame.column_names () будет функцией в пандах, но, поскольку это не так, возможно, было бы неплохо использовать следующий синтаксис. Это каким-то образом сохраняет ощущение, что вы используете панды надлежащим образом, вызывая функцию «tolist»: frame.columns.tolist ()

frame.columns.tolist() 

0

Если у DataFrame есть Index или MultiIndex, и вы хотите, чтобы они также были включены в качестве имен столбцов:

names = list(filter(None, df.index.names + df.columns.values.tolist()))

Это позволяет избежать вызова метода reset_index (), который приводит к ненужному снижению производительности для такой простой операции.

Я сталкивался с необходимостью это чаще, потому что я перемещаю данные из баз данных, где индекс информационного кадра сопоставляется с первичным / уникальным ключом, но для меня это просто еще один «столбец». Вероятно, для панд имеет смысл иметь встроенный метод для чего-то подобного (вполне возможно, что я его пропустил).


-1

Это решение перечисляет все столбцы вашего объекта my_dataframe:

print(list(my_dataframe))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.