Nhận danh sách từ các tiêu đề cột DataFrame của gấu trúc


1015

Tôi muốn nhận danh sách các tiêu đề cột từ DataFrame của gấu trúc. DataFrame sẽ đến từ đầu vào của người dùng vì vậy tôi sẽ không biết sẽ có bao nhiêu cột hoặc chúng sẽ được gọi là gì.

Ví dụ: nếu tôi được cung cấp một DataFrame như thế này:

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

Tôi muốn có một danh sách như thế này:

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

Câu trả lời:


1646

Bạn có thể lấy các giá trị dưới dạng danh sách bằng cách thực hiện:

list(my_dataframe.columns.values)

Ngoài ra, bạn có thể chỉ cần sử dụng: (như thể hiện trong câu trả lời của Ed Chum ):

list(my_dataframe)

42
Tại sao tài liệu này không có columnsnhư một thuộc tính?
Tjorriemorrie

@Tjorriemorrie: Tôi không chắc chắn, nó có thể phải làm theo cách họ tự động tạo tài liệu của họ. Nó được đề cập ở những nơi khác mặc dù: pandas.pydata.org/pandas-docs/ sóng / 19
Simeon Visser

8
Tôi đã mong đợi một cái gì đó như df.column_names(). Câu trả lời này vẫn đúng hay đã lỗi thời?
alvas

1
@alvas có nhiều cách khác để làm điều đó (xem các câu trả lời khác trên trang này) nhưng theo tôi biết không có phương pháp nào trên khung dữ liệu trực tiếp để tạo danh sách.
Simeon Visser

19
Điều quan trọng, điều này bảo tồn thứ tự cột.
WindChimes

402

Có một phương thức được xây dựng là hiệu quả nhất:

my_dataframe.columns.values.tolist()

.columnstrả về một Index, .columns.valuestrả về một mảng và cái này có chức năng trợ giúp .tolistđể trả về một danh sách.

Nếu hiệu suất không quan trọng với bạn, Indexcác đối tượng xác định một .tolist()phương thức mà bạn có thể gọi trực tiếp:

my_dataframe.columns.tolist()

Sự khác biệt về hiệu suất là rõ ràng:

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

Đối với những người ghét đánh máy, bạn chỉ có thể gọi listvề df, như vậy:

list(df)

4
Không bỏ phiếu, nhưng muốn giải thích: không dựa vào chi tiết triển khai, sử dụng "giao diện công cộng" của DataFrame. Nghĩ về vẻ đẹp của df.keys ()
Sascha Gottfried

3
@SaschaGottfried việc thực hiện DataFrameiterable đã không thay đổi kể từ ngày đầu tiên: pandas.pydata.org/pandas-docs/ sóng / basics.html # itertation . Lặp lại được trả về từ DataFrame luôn là các cột, do đó, việc thực hiện for col in df:phải luôn luôn hoạt động giống nhau trừ khi các nhà phát triển có một meltdown vì vậy list(df)và vẫn phải là một phương thức hợp lệ. Lưu ý rằng việc df.keys()gọi vào thực hiện bên trong cấu trúc giống như chính tả trả về các khóa là các cột. Downvote không thể giải thích là thiệt hại tài sản thế chấp được dự kiến ​​trên SO vì vậy đừng lo lắng
EdChum

Tôi đã đề cập đến các chi tiết thực hiện của columnsthuộc tính. Một giờ trước tôi đã đọc về Law of Demeter quảng cáo rằng người gọi không nên phụ thuộc vào việc điều hướng mô hình đối tượng bên trong. list(df)không chuyển đổi loại rõ ràng. Tác dụng phụ đáng chú ý: thời gian thực hiện và tăng mức tiêu thụ bộ nhớ với df.keys()phương pháp kích thước khung dữ liệu là một phần của bản chất giống như chính tả của a DataFrame. Thực tế đáng chú ý: thời gian thực hiện cho df.keys()khá ổn định bất kể kích thước khung dữ liệu - một phần trách nhiệm của các nhà phát triển gấu trúc.
Sascha Gottfried

1
@SaschaGottfried Tôi có thể thêm câu này vào câu trả lời của mình và ghi nhận rằng bạn không thấy ai khác bao gồm điều này
EdChum

1
Tôi có thể thấy giá trị trong câu trả lời cũng như trong các bình luận - không cần thay đổi gì cả.
Sascha Gottfried

89

Đã thực hiện một số thử nghiệm nhanh và có lẽ không ngạc nhiên khi phiên bản tích hợp sử dụng dataframe.columns.values.tolist()là nhanh nhất:

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

(Tôi vẫn thực sự thích list(dataframe)mặc dù vậy, cảm ơn EdChum!)


47

Nó thậm chí còn đơn giản hơn (bởi gấu trúc 0.16.0):

df.columns.tolist()

sẽ cung cấp cho bạn các tên cột trong một danh sách tốt đẹp.


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

Để liệt kê các cột của khung dữ liệu trong khi ở chế độ gỡ lỗi, hãy sử dụng cách hiểu danh sách:

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

Nhân tiện, bạn có thể nhận được một danh sách được sắp xếp đơn giản bằng cách sử dụng sorted:

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

Điều đó sẽ list(df)chỉ làm việc với các datafram tự động? Hoặc nó hoạt động cho tất cả các dataframes?
alvas

2
Nên làm việc cho tất cả. Tuy nhiên, khi bạn đang ở trong trình gỡ lỗi, bạn cần sử dụng một sự hiểu biết danh sách [c for c in df].
Alexander

25

Ngạc nhiên là tôi chưa thấy bài này được đăng cho đến nay, vì vậy tôi sẽ để nó ở đây.

Giải nén mở rộng lặp lại (python3.5 +): [*df]và bạn bè

Giải nén các khái quát hóa (PEP 448) đã được giới thiệu với Python 3.5. Vì vậy, các hoạt động sau đây là tất cả có thể.

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 

Nếu bạn muốn một list....

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

Hoặc, nếu bạn muốn một set,

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

Hoặc, nếu bạn muốn một tuple,

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

Hoặc, nếu bạn muốn lưu trữ kết quả ở đâu đó,

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

... Nếu bạn là kiểu người chuyển đổi cà phê thành gõ âm thanh, thì điều này sẽ tiêu thụ cà phê của bạn hiệu quả hơn;)

PS: nếu hiệu suất là quan trọng, bạn sẽ muốn bỏ các giải pháp ở trên để ủng hộ

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

Điều này tương tự như câu trả lời của Ed Chum , nhưng được cập nhật cho v0.24, nơi .to_numpy()được ưu tiên sử dụng .values. Xem câu trả lời này (bởi tôi) để biết thêm thông tin.

Kiểm tra trực quan
Vì tôi đã thấy điều này được thảo luận trong các câu trả lời khác, bạn có thể sử dụng giải nén lặp lại (không cần các vòng lặp rõ ràng).

print(*df)
A B C

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

Phê bình các phương pháp khác

Không sử dụng một forvòng lặp rõ ràng cho một hoạt động có thể được thực hiện trong một dòng duy nhất (Việc hiểu danh sách là ổn).

Tiếp theo, sử dụng sorted(df) không bảo toàn thứ tự ban đầu của các cột. Đối với điều đó, bạn nên sử dụng list(df)thay thế.

Tiếp theo, list(df.columns)list(df.columns.values)là những gợi ý kém (như phiên bản hiện tại, v0.24). Cả hai mảng (được trả Indexvề từ df.columns) và NumPy (được trả về bởi df.columns.values) đều xác định .tolist()phương thức nhanh hơn và thành ngữ hơn.

Cuối cùng, danh sách nghĩa là, list(df)chỉ nên được sử dụng như là một thay thế ngắn gọn cho các phương pháp đã nói ở trên cho python <= 3,4 khi không giải nén được mở rộng.


24

Đó là có sẵn như my_dataframe.columns.


1
Và rõ ràng là một danh sách củaheader_list = list(my_dataframe.columns)
yeliabsalohcin

^ Hoặc tốt hơn vẫn là : df.columns.tolist().
cs95

18

Điều đó thật thú vị nhưng df.columns.values.tolist()nhanh hơn gần 3 lần df.columns.tolist()nhưng tôi nghĩ rằng chúng giống nhau:

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
Thời gian đã được bao phủ trong câu trả lời này . Lý do cho sự khác biệt là bởi vì .valuestrả về mảng numpy bên dưới, và làm một cái gì đó với numpy hầu như luôn nhanh hơn so với làm trực tiếp điều tương tự với gấu trúc.
cs95

17

Một DataFrame tuân theo quy ước giống như chính tả của việc lặp lại trên các khóa của cơ sở dữ liệu của các đối tượng.

my_dataframe.keys()

Tạo một danh sách các khóa / cột - phương thức đối tượng to_list()và cách pythonic

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

Lặp lại cơ bản trên DataFrame trả về nhãn cột

[column for column in my_dataframe]

Không chuyển đổi DataFrame thành một danh sách, chỉ để lấy nhãn cột. Đừng ngừng suy nghĩ trong khi tìm kiếm các mẫu mã thuận tiện.

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
Thử nghiệm của tôi cho thấy df.columnslà nhanh hơn rất nhiều df.keys(). Không chắc chắn tại sao chúng có cả chức năng và thuộc tính cho cùng một thứ (vâng, đây không phải là lần đầu tiên tôi thấy 10 cách khác nhau để làm điều gì đó trong gấu trúc).
cs95

1
Mục đích của câu trả lời của tôi là chỉ ra một vài cách để truy vấn nhãn cột từ DataFrame và làm nổi bật một mẫu chống hiệu năng. Tuy nhiên, tôi thích ý kiến ​​của bạn và nêu lên câu trả lời gần đây của bạn - vì chúng cung cấp giá trị từ quan điểm kỹ thuật phần mềm.
Sascha Gottfried

14

Trong vở

Để khám phá dữ liệu trong sổ ghi chép IPython, cách ưa thích của tôi là:

sorted(df)

Mà sẽ tạo ra một danh sách theo thứ tự bảng chữ cái dễ đọc.

Trong kho lưu trữ mã

Trong mã tôi thấy nó rõ ràng hơn để làm

df.columns

Bởi vì nó cho người khác đọc mã của bạn những gì bạn đang làm.


sorted(df)thay đổi thứ tự. Sử dụng cẩn thận.
cs95

@coldspeed Tôi có đề cập đến điều này mặc dù "Điều này sẽ tạo ra một danh sách theo thứ tự bảng chữ cái dễ đọc."
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

như được trả lời bởi Simeon Visser ... bạn có thể làm

list(my_dataframe.columns.values) 

hoặc là

list(my_dataframe) # for less typing.

Nhưng tôi nghĩ rằng hầu hết các điểm ngọt ngào là:

list(my_dataframe.columns)

Đó là rõ ràng, đồng thời không dài không cần thiết.


"Đó là rõ ràng, đồng thời không dài không cần thiết." Tôi không đồng ý. Gọi điện listkhông có giá trị trừ khi bạn gọi dftrực tiếp (ví dụ, sự đồng nhất). Truy cập .columnsthuộc tính trả về một Indexđối tượng có một tolist()phương thức được xác định trên nó và gọi đó là thành ngữ hơn là liệt kê Index. Trộn các thành ngữ chỉ vì mục đích hoàn chỉnh không phải là một ý tưởng tuyệt vời. Tương tự như vậy để liệt kê các mảng bạn nhận được từ .values.
cs95

3

Để kiểm tra nhanh, gọn gàng, trực quan, hãy thử điều này:

for col in df.columns:
    print col

3

Điều này cho chúng ta tên của các cột trong danh sách:

list(my_dataframe.columns)

Một hàm khác gọi là tolist () cũng có thể được sử dụng:

my_dataframe.columns.tolist()

Điều này đã được bao phủ trong các câu trả lời khác. Giải pháp đầu tiên của bạn cũng trộn lẫn các thành ngữ, đó không phải là một ý tưởng tuyệt vời. Xem bình luận của tôi dưới một câu trả lời khác.
cs95

2

Tôi cảm thấy câu hỏi xứng đáng được giải thích thêm.

Như @fixxxer đã lưu ý, câu trả lời phụ thuộc vào phiên bản gấu trúc bạn đang sử dụng trong dự án của mình. Mà bạn có thể nhận được với pd.__version__lệnh.

Nếu bạn vì một số lý do như tôi (trên debian jessie tôi sử dụng 0.14.1) sử dụng phiên bản gấu trúc cũ hơn 0.16.0, thì bạn cần sử dụng:

df.keys().tolist()bởi vì chưa có df.columnsphương pháp nào được thực hiện

Ưu điểm của phương pháp khóa này là, nó hoạt động ngay cả trong phiên bản mới hơn của gấu trúc, vì vậy nó phổ biến hơn.


Con của khóa () là một lệnh gọi hàm chứ không phải là tra cứu thuộc tính, vì vậy nó sẽ luôn chậm hơn. Tất nhiên, với thời gian truy cập liên tục, không ai thực sự quan tâm đến sự khác biệt như thế này, nhưng tôi nghĩ dù sao nó cũng đáng được đề cập; df.columns hiện là một thành ngữ được chấp nhận rộng rãi hơn để truy cập các tiêu đề.
cs95

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

6
xin vui lòng thay thế nó với một sự hiểu biết danh sách.
Sascha Gottfried

4
thay đổi 3 dòng đầu tiên của bạn thành[n for n in dataframe.columns]
Anton Protopopov 4/12/2015

Tại sao bạn muốn trải qua tất cả rắc rối này cho một thao tác bạn có thể dễ dàng thực hiện trong một dòng duy nhất?
cs95

0

Mặc dù giải pháp được cung cấp ở trên là tốt đẹp. Tôi cũng mong muốn một cái gì đó như frame.column_names () là một hàm trong gấu trúc, nhưng vì nó không phải vậy, có lẽ sẽ rất tuyệt nếu sử dụng cú pháp sau. Nó bằng cách nào đó duy trì cảm giác rằng bạn đang sử dụng gấu trúc một cách thích hợp bằng cách gọi hàm "tolist": frame.columns.tolist ()

frame.columns.tolist() 

0

Nếu DataFrame xảy ra có Index hoặc Multi Index và bạn cũng muốn những cái đó được bao gồm dưới dạng tên cột:

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

Nó tránh việc gọi reset_index () có hiệu năng không cần thiết cho một thao tác đơn giản như vậy.

Tôi đã gặp phải nhu cầu này thường xuyên hơn vì tôi chuyển dữ liệu từ cơ sở dữ liệu trong đó chỉ mục khung dữ liệu ánh xạ tới khóa chính / duy nhất, nhưng thực sự chỉ là một "cột" khác đối với tôi. Có lẽ sẽ có ý nghĩa khi gấu trúc có một phương pháp tích hợp cho một cái gì đó như thế này (hoàn toàn có thể tôi đã bỏ lỡ nó).


-1

Giải pháp này liệt kê tất cả các cột của đối tượng my_dataframe của bạn:

print(list(my_dataframe))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.