Отримайте список із заголовків стовпців панд DataFrame


1013

Я хочу отримати список заголовків стовпців від пандес 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']

Відповіді:


1644

Значення можна отримати у списку, виконавши:

list(my_dataframe.columns.values)

Також ви можете просто використовувати: (як показано у відповіді Еда Чума ):

list(my_dataframe)

42
Чому цей документ не є columnsатрибутом?
Tjorriemorrie

@Tjorriemorrie: Я не впевнений, це може мати відношення до того, як вони автоматично генерують свою документацію. Він згадується в інших місцях: pandas.pydata.org/pandas-docs/stable/…
Simeon Visser

8
Я б очікував чогось подібного df.column_names(). Ця відповідь все-таки правильна чи вона застаріла?
alvas

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

19
Важливо, що це зберігає порядок стовпців.
WindChimes

402

Існує вбудований метод, який є найбільш ефективним:

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()викликає внутрішню реалізацію структури, що нагадує дікт, повертаючи ключі, що є стовпцями. Нездійсненний потік - це побічний збиток, який слід очікувати на
ТА,

Я переглянув деталі реалізації columnsатрибута. Годину тому я читав про Закон Деметера, що сприяє тому, що абонент не повинен залежати від навігації по внутрішній моделі об'єкта. list(df)робить явне перетворення типів. Помітний побічний ефект: збільшення часу виконання та споживання пам’яті df.keys()методом розміру рамки даних є частиною диктуючого характеру 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]та Friends

Розпакування узагальнень (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()метод, який є швидшим і ідіоматичнішим.

Нарешті, розписання, тобто, 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метод.

Перевага цього методу ключів полягає в тому, що він працює навіть у більш новій версії панд, тому він більш універсальний.


Мінус ключів () полягає в тому, що це виклик функції, а не пошук атрибутів, тому це завжди буде повільніше. Звичайно, при постійних доступах у часі ніхто насправді не переймається подібними відмінностями, але я думаю, що це все одно варто згадати; df.column тепер є більш загальноприйнятою фразою для доступу до заголовків.
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.column.tolist ()

frame.columns.tolist() 

0

Якщо у DataFrame є індекс або 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.