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

1195

Я хочу получить список заголовков столбцов из Pandas 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']
2
1870

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

list(my_dataframe.columns.values)

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

list(my_dataframe)
12
  • 46
    Почему у этого документа нет columnsатрибута? 21 ноя '14 в 8:30
  • 9
    Я ожидал чего-то подобного df.column_names(). Этот ответ все еще верен или устарел?
    alvas
    13 янв.
  • 1
    @alvas есть несколько других способов сделать это (см. другие ответы на этой странице), но, насколько я знаю, в кадре данных нет метода для создания списка напрямую. 13 янв.
  • 21 год
    Важно отметить, что это сохраняет порядок столбцов. 25 янв.
  • 1
    Этот первый вариант ужасен (для текущей версии pandas - v0.24), потому что он смешивает идиомы . Если у вас возникли проблемы с доступом к массиву numpy, используйте .tolist()вместо этого метод, он быстрее и идиоматичнее.
    cs95
    3 апр '19 в 9:50
472

Существует встроенный метод, который является наиболее производительным:

my_dataframe.columns.values.tolist()

.columnsвозвращает Index, .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)
103

Я провел несколько быстрых тестов, и, возможно, неудивительно, что встроенная версия с ее использованием 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 !)

0
61

Становится еще проще (Pandas 0.16.0):

df.columns.tolist()

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

44

Расширенная итерабельная распаковка (Python 3.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']

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

P.S.: if performance is important, you will want to ditch the solutions above in favour of

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

This is similar to Ed Chum's answer, but updated for v0.24 where .to_numpy() is preferred to the use of .values. See this answer (by me) for more information.

Визуальная проверка

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

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()метод, который является более быстрым и идиоматическим.

Наконец, лизис, т.е. его list(df)следует использовать только как краткую альтернативу вышеупомянутым методам для Python 3.4 или более ранних версий, где расширенная распаковка недоступна.

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

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

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

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

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']
2
  • Будет ли это list(df)работать только с фреймами данных с автоинкрементом? Или это работает для всех фреймов данных?
    alvas
    13 янв.
  • 2
    Должно работать для всех. Однако, когда вы находитесь в отладчике, вам нужно использовать понимание списка [c for c in df]. 13 янв.
26

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

2
  • 1
    И явно в виде списка header_list = list(my_dataframe.columns) 5 сен '17 в 12:59
  • 1
    ^ Или еще лучше: df.columns.tolist().
    cs95
    3 апр '19 в 9:52
20

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

my_dataframe.keys()

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

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
  • 2
    Мои тесты показывают df.columnsнамного быстрее df.keys(). Не уверен, почему у них есть и функция, и атрибут для одного и того же (ну, это не первый раз, когда я вижу 10 разных способов сделать что-то в пандах).
    cs95
    3 апр '19 в 9:45
  • 1
    Мой ответ состоял в том, чтобы показать несколько способов запроса меток столбцов из DataFrame и выделить антипаттерн производительности. Тем не менее мне нравятся ваши комментарии, и я поддержал ваш недавний ответ, поскольку они представляют ценность с точки зрения разработки программного обеспечения. 9 апр '19 в 10:05
20

Интересно, но df.columns.values.tolist()почти в три раза быстрее 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
1
  • 2
    Сроки уже были рассмотрены в этом ответе . Причина несоответствия заключается в том, что .valuesвозвращает базовый массив numpy, а выполнение чего-либо с numpy почти всегда быстрее, чем выполнение того же самого с pandas напрямую.
    cs95
    3 апр '19 в 9:48
15

В записной книжке

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

sorted(df)

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

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

В коде я считаю более явным сделать

df.columns

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

2
  • sorted(df)меняет порядок. Используйте с осторожностью.
    cs95
    3 апр '19 в 9:45
  • @coldspeed Я все же упоминаю об этом, «что позволит создать удобный для чтения список в алфавитном порядке». 3 апр '19 в 11:48
10
%%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)
1
  • Объяснение было бы в порядке. Например, что такое резюме и заключение? Пожалуйста, ответьте, отредактировав (изменив) свой ответ , а не здесь, в комментариях ( без «Изменить:», «Обновить:» и т. Д. - ответ должен появиться так, как если бы он был написан сегодня). 41 секунду назад
4

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

for col in df.columns:
    print col
4

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

list(my_dataframe.columns.values)

или

list(my_dataframe) # For less typing.

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

list(my_dataframe.columns)

Он явный и в то же время не излишне длинный.

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

Я считаю, что этот вопрос заслуживает дополнительного пояснения.

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

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

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

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

1
  • Недостаток keys () в том, что это вызов функции, а не поиск атрибутов, поэтому он всегда будет медленнее. Конечно, при постоянном доступе по времени никто особо не заботится о подобных различиях, но я думаю, что в любом случае стоит упомянуть; df.columns теперь является более общепринятой идиомой для доступа к заголовкам.
    cs95
    4 апр '19 в 21:00
2
n = []
for i in my_dataframe.columns:
    n.append(i)
print n
3
  • 6
    пожалуйста, замените его пониманием списка. 23 янв.
  • 4
    измените свои первые 3 строки на [n for n in dataframe.columns] 4 дек.
  • Зачем вам проходить через все эти неприятности для операции, которую легко выполнить в одной строке?
    cs95
    3 апр '19 в 9:36
1

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

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

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

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

1

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

frame.columns.tolist()
1
  • Относительно «решения» : о каком из них вы имеете в виду? Или вы ссылаетесь на несколько решений? 7 минут назад