Pobierz listę z nagłówków kolumn pandy DataFrame

1013

Chcę uzyskać listę nagłówków kolumn z pandy DataFrame. DataFrame będzie pochodzić z danych wprowadzanych przez użytkownika, więc nie będę wiedział, ile kolumn będzie i jak będą one nazywane.

Na przykład, jeśli otrzymam DataFrame w ten sposób:

>>> 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

Chciałbym uzyskać taką listę:

>>> header_list
['y', 'gdp', 'cap']
natsuki_2002
źródło

Odpowiedzi:

1644

Możesz uzyskać wartości jako listę, wykonując:

list(my_dataframe.columns.values)

Możesz także po prostu użyć: (jak pokazano w odpowiedzi Eda Chuma ):

list(my_dataframe)
Simeon Visser
źródło
42
Dlaczego ten dokument nie ma columnsjako atrybutu?
Tjorriemorrie
@Tjorriemorrie: Nie jestem pewien, może to mieć związek ze sposobem, w jaki automatycznie generują swoją dokumentację. Jest jednak wspomniany w innych miejscach: pandas.pydata.org/pandas-docs/stable/…
Simeon Visser
8
Spodziewałbym się czegoś takiego df.column_names(). Czy ta odpowiedź jest nadal poprawna, czy jest nieaktualna?
alvas
1
@alvas istnieje wiele innych sposobów na zrobienie tego (zobacz inne odpowiedzi na tej stronie), ale o ile wiem, nie ma metody na ramce danych bezpośrednio do tworzenia listy.
Simeon Visser
19
Co ważne, zachowuje to kolejność kolumn.
WindChimes
402

Istnieje wbudowana metoda, która jest najbardziej wydajna:

my_dataframe.columns.values.tolist()

.columnszwraca indeks, .columns.valueszwraca tablicę, która ma funkcję pomocniczą, .tolistktóra zwraca listę.

Jeśli wydajność nie jest dla Ciebie tak ważna, Indexobiekty definiują .tolist()metodę, którą można wywołać bezpośrednio:

my_dataframe.columns.tolist()

Różnica w wydajności jest oczywista:

%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)

Dla tych, którzy nie lubią pisać, można po prostu zadzwonić listna df, a więc:

list(df)
EdChum
źródło
4
Nie oddałem głosu, ale chcę wyjaśnić: nie polegaj na szczegółach implementacji, użyj „publicznego interfejsu” DataFrame. Pomyśl o pięknie df.keys ()
Sascha Gottfried
3
@SaschaGottfried wdrożenie iteracji DataFramenie zmieniło się od pierwszego dnia: pandas.pydata.org/pandas-docs/stable/basics.html#iteration . Iterowalną wartością zwracaną z DataFrame zawsze były kolumny, więc działanie for col in df:powinno zawsze zachowywać się tak samo, chyba że programiści mają takie załamanie list(df)i nadal powinna być poprawną metodą. Zauważ, że df.keys()wywołuje wewnętrzną implementację struktury przypominającej dict, zwracając klucze, które są kolumnami. Niewytłumaczalne negatywne opinie to dodatkowe szkody, których należy się spodziewać na SO, więc nie martw się
EdChum
Odniosłem się do szczegółów implementacji columnsatrybutu. Godzinę temu czytałem o prawie Demeter promującym, że osoba dzwoniąca nie powinna polegać na nawigacji po wewnętrznym modelu obiektowym. list(df)dokonuje jawnej konwersji typu. Znaczący efekt uboczny: czas wykonania i wzrost zużycia pamięci przy metodzie rozmiaru ramki df.keys()danych jest częścią dyktatorskiej natury a DataFrame. Godny uwagi fakt: czas wykonania df.keys()jest raczej stały, niezależnie od wielkości ramki danych - część odpowiedzialności twórców pand.
Sascha Gottfried
1
@SaschaGottfried Mogę dodać to do mojej odpowiedzi i wyrazić uznanie, ponieważ nikt tego nie
dodał
1
Widzę wartość w danej odpowiedzi, a także w komentarzach - nie trzeba niczego zmieniać.
Sascha Gottfried
89

Przeprowadziłem kilka szybkich testów i być może nie jest zaskoczeniem, że wbudowana wersja dataframe.columns.values.tolist()jest najszybsza:

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

(Wciąż jednak bardzo mi się podoba list(dataframe), więc dzięki EdChum!)

tegan
źródło
47

To staje się jeszcze prostsze (według pand 0.16.0):

df.columns.tolist()

poda ci nazwy kolumn na ładnej liście.

fixxxer
źródło
37
>>> list(my_dataframe)
['y', 'gdp', 'cap']

Aby wyświetlić listę kolumn ramki danych w trybie debuggera, skorzystaj ze zrozumienia listy:

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

Nawiasem mówiąc, możesz uzyskać posortowaną listę, po prostu używając sorted:

>>> sorted(my_dataframe)
['cap', 'gdp', 'y']
Alexander
źródło
Czy list(df)działałoby to tylko w przypadku ramek danych z autoinkrementacją? Czy działa to dla wszystkich ramek danych?
alvas
2
Powinien działać dla wszystkich. Jednak podczas debugowania musisz korzystać ze zrozumienia listy [c for c in df].
Alexander
25

Zaskoczony, jak dotąd nie widziałem tego, więc zostawię to tutaj.

Extended Iterable Unpacking (python3.5 +): [*df]and Friends

Rozpakowywanie uogólnień (PEP 448) zostało wprowadzone w Pythonie 3.5. Zatem wszystkie poniższe operacje są możliwe.

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 

Jeśli chcesz list....

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

Lub, jeśli chcesz set,

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

Lub, jeśli chcesz tuple,

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

Lub, jeśli chcesz gdzieś zapisać wynik,

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

... jeśli jesteś typem osoby, która zamienia kawę na dźwięki pisania, cóż, dzięki temu będziesz spożywać kawę bardziej efektywnie;)

PS: jeśli wydajność jest ważna, warto porzucić powyższe rozwiązania na korzyść

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

Jest to podobne do odpowiedzi Eda Chuma, ale zaktualizowane do wersji v0.24, w której .to_numpy()preferowane jest użycie .values. Zobacz tę odpowiedź (przeze mnie), aby uzyskać więcej informacji.

Kontrola wizualna
Ponieważ widziałem to omówione w innych odpowiedziach, możesz użyć iterowalnego rozpakowywania (nie ma potrzeby jawnych pętli).

print(*df)
A B C

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

Krytyka innych metod

Nie używaj wyraźnej forpętli dla operacji, które można wykonać w jednym wierszu (rozumienie listy jest w porządku).

Następnie użycie sorted(df) nie zachowuje oryginalnej kolejności kolumn. W tym celu należy użyć list(df)zamiast tego.

Dalej, list(df.columns)i list(df.columns.values)są kiepskie sugestie (od bieżącej wersji, v0.24). Zarówno Index(zwrócone z df.columns), jak i NumPy (zwrócone przez df.columns.values) definiują .tolist()metodę, która jest szybsza i bardziej idiomatyczna.

Wreszcie, listifikacja, tj. list(df)Powinna być używana jedynie jako zwięzła alternatywa dla wyżej wymienionych metod dla Pythona <= 3.4, gdzie rozszerzone rozpakowywanie nie jest dostępne.

cs95
źródło
24

To jest dostępne jako my_dataframe.columns.

BrenBarn
źródło
1
I wyraźnie jako listaheader_list = list(my_dataframe.columns)
yeliabsalohcin
^ Albo jeszcze lepiej: df.columns.tolist().
cs95
18

To ciekawe, ale df.columns.values.tolist()jest prawie 3 razy szybsze, df.columns.tolist()ale myślałem, że są takie same:

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
Anton Protopopov
źródło
2
Czasy zostały już uwzględnione w tej odpowiedzi . Przyczyną rozbieżności jest to, że .valueszwraca podstawową tablicę numpy, a robienie czegoś za pomocą numpy jest prawie zawsze szybsze niż robienie tego samego z pandami bezpośrednio.
cs95
17

DataFrame następuje dict-Like konwencji iteracji nad „klucze” z przedmiotami.

my_dataframe.keys()

Utwórz listę kluczy / kolumn - metoda obiektowa to_list()i sposób pythonowy

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

Podstawowa iteracja na DataFrame zwraca etykiety kolumn

[column for column in my_dataframe]

Nie konwertuj DataFrame na listę, aby uzyskać etykiety kolumn. Nie przestawaj myśleć, szukając wygodnych próbek kodu.

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)
Sascha Gottfried
źródło
2
Moje testy pokazują, że df.columnsjest dużo szybszy niż df.keys(). Nie jestem pewien, dlaczego mają zarówno funkcję, jak i atrybut tej samej rzeczy (cóż, nie po raz pierwszy widziałem 10 różnych sposobów robienia czegoś w pandach).
cs95
1
Zamiarem mojej odpowiedzi było pokazanie kilku sposobów przeszukiwania etykiet kolumn z DataFrame i podkreślenie anty-wzorca wydajności. Niemniej jednak podoba mi się twoje komentarze i głosowałem za twoją ostatnią odpowiedzią - ponieważ zapewniają one wartość z punktu widzenia inżynierii oprogramowania.
Sascha Gottfried
14

W notatniku

Do eksploracji danych w notatniku IPython preferuję:

sorted(df)

Które stworzy czytelną listę uporządkowaną alfabetycznie.

W repozytorium kodu

W kodzie uważam, że jest to bardziej wyraźne

df.columns

Ponieważ mówi innym, czytając twój kod, co robisz.

firelynx
źródło
sorted(df)zmienia kolejność. Używaj ostrożnie.
cs95
@coldspeed Wspominam o tym jednak „Które stworzy łatwą do odczytania listę uporządkowaną alfabetycznie”.
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)
rohit singh
źródło
3

jak odpowiedział Simeon Visser ... możesz to zrobić

list(my_dataframe.columns.values) 

lub

list(my_dataframe) # for less typing.

Ale myślę, że najbardziej podoba się to:

list(my_dataframe.columns)

Jest to wyraźne, a jednocześnie niepotrzebnie długie.

Vivek
źródło
„Jest to jednoznaczne, a jednocześnie niepotrzebnie długie”. Nie zgadzam się. Dzwonienie listnie ma żadnej wartości, chyba że dzwonisz dfbezpośrednio (na przykład zwięzłość). Uzyskiwanie dostępu do .columnsatrybutu zwraca Indexobiekt, który ma tolist()zdefiniowaną metodę, a wywoływanie jest bardziej idiomatyczne niż wyświetlanie listy Index. Mieszanie idiomów dla samej kompletności nie jest świetnym pomysłem. To samo dotyczy listowania tablicy, którą otrzymujesz .values.
cs95
3

Aby szybko, schludnie i wizualnie sprawdzić, spróbuj tego:

for col in df.columns:
    print col
Joseph True
źródło
3

To daje nam nazwy kolumn na liście:

list(my_dataframe.columns)

Można również użyć innej funkcji o nazwie tolist ():

my_dataframe.columns.tolist()
Harikrishna
źródło
Zostało to już omówione w innych odpowiedziach. Twoje pierwsze rozwiązanie łączy również idiomy, co nie jest świetnym pomysłem. Zobacz mój komentarz pod inną odpowiedzią.
cs95
2

Wydaje mi się, że pytanie zasługuje na dodatkowe wyjaśnienie.

Jak zauważył @fixxxer, odpowiedź zależy od wersji pandy, której używasz w swoim projekcie. Które można uzyskać za pomocą pd.__version__polecenia.

Jeśli jesteś z jakiegoś powodu takiego jak ja (na Debianie Jessie używam 0.14.1), używając starszej wersji pand niż 0.16.0, musisz użyć:

df.keys().tolist()ponieważ nie ma df.columnsjeszcze zaimplementowanej metody.

Zaletą tej metody kluczy jest to, że działa ona nawet w nowszej wersji pand, więc jest bardziej uniwersalna.

StefanK
źródło
Przeciwieństwem funkcji keys () jest to, że jest to wywołanie funkcji, a nie wyszukiwanie atrybutów, więc zawsze będzie wolniejsze. Oczywiście przy stałym dostępie do czasu nikt tak naprawdę nie dba o takie różnice, ale myślę, że i tak warto o tym wspomnieć; df.columns jest teraz bardziej powszechnie akceptowanym idiomem dostępu do nagłówków.
cs95
1
n = []
for i in my_dataframe.columns:
    n.append(i)
print n
użytkownik21988
źródło
6
proszę zastąpić go zrozumieniem listy.
Sascha Gottfried
4
zmień swoje pierwsze 3 linie na[n for n in dataframe.columns]
Anton Protopopov
Dlaczego miałbyś chcieć przejść przez te wszystkie kłopoty z operacją, którą możesz łatwo wykonać w jednej linii?
cs95,
0

Mimo że powyższe rozwiązanie jest dobre. Spodziewałbym się również, że coś w rodzaju frame.column_names () będzie funkcją w pandach, ale skoro tak nie jest, być może lepiej byłoby użyć następującej składni. W pewien sposób zachowuje wrażenie, że używasz pand we właściwy sposób, wywołując funkcję „tolist”: frame.columns.tolist ()

frame.columns.tolist() 
Igor Jakovljevic
źródło
0

Jeśli zdarzenie DataFrame ma indeks lub indeks MultiIndex, a Ty chcesz, aby te również zostały uwzględnione jako nazwy kolumn:

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

Pozwala to uniknąć wywoływania reset_index (), który ma niepotrzebny spadek wydajności w przypadku tak prostej operacji.

Potrzebuję tego częściej, ponieważ przesyłam dane z baz danych, w których indeks ramki danych jest mapowany na klucz podstawowy / unikalny, ale tak naprawdę jest to dla mnie kolejna „kolumna”. Prawdopodobnie sensownym byłoby, gdyby pandy miały wbudowaną metodę dla czegoś takiego (całkowicie możliwe, że tego nie zauważyłem).

totalhack
źródło
-1

To rozwiązanie wyświetla wszystkie kolumny obiektu my_dataframe:

print(list(my_dataframe))
Sunitha G.
źródło