2012-06-16 75 views
134

Tôi có một dataframe với hơn 200 cột (không hỏi tại sao). Vấn đề là khi chúng được tạo ra trật tự đượcPython Pandas - Sắp xếp lại các cột trong một khung dữ liệu dựa trên tên cột

['Q1.3','Q6.1','Q1.2','Q1.1',......] 

tôi cần phải sắp xếp lại các cột như sau:

['Q1.1','Q1.2','Q1.3',.....'Q6.1',......] 

Có một số cách để tôi làm điều này trong python?

+16

Tại sao bạn có 200 cột không? ;) –

+0

Bản sao có thể có của [Cách thay đổi thứ tự của các cột DataFrame?] (Https://stackoverflow.com/questions/13148429/how-to-change-the-order-of-dataframe-columns) –

Trả lời

171
df.reindex_axis(sorted(df.columns), axis=1) 

Giả định rằng việc sắp xếp tên cột sẽ cung cấp thứ tự bạn muốn. Nếu tên cột của bạn sẽ không sắp xếp theo từ điển (ví dụ: nếu bạn muốn cột Q10.3 xuất hiện sau Q9.1), bạn sẽ cần phân loại khác nhau, nhưng điều đó không liên quan gì đến gấu trúc.

+2

Tôi thích điều này vì cùng một phương thức có thể được sử dụng để sắp xếp các hàng (tôi cần sắp xếp các hàng và cột). Trong khi đó là phương thức tương tự, bạn có thể bỏ qua đối số 'axis' (hoặc cung cấp giá trị mặc định của nó,' 0'), như 'df.reindex_axis (được sắp xếp (non_sorted_row_index))' tương đương với 'df.reindex (được sắp xếp (non_sorted_row_index))) ' –

+0

Lưu ý rằng việc lập chỉ mục lại không được thực hiện tại chỗ, do đó, để thực sự áp dụng sắp xếp cho df, bạn phải sử dụng' df = df.reindex_axis (...) '. Ngoài ra, lưu ý rằng các loại không phải từ vựng rất dễ dàng với cách tiếp cận này, vì danh sách các tên cột có thể được sắp xếp riêng biệt thành một thứ tự tùy ý và sau đó được chuyển đến 'reindex_axis'. Điều này là không thể với phương pháp thay thế được đề xuất bởi @Wes McKinney ('df = df.sort_index (axis = 1)'), tuy nhiên nó sạch hơn đối với các loại từ điển thuần túy. – WhoIsJack

0

Các sort phương pháp và sorted chức năng cho phép bạn để cung cấp một chức năng tùy chỉnh để trích xuất các phím được sử dụng để so sánh:

>>> ls = ['Q1.3', 'Q6.1', 'Q1.2'] 
>>> sorted(ls, key=lambda x: float(x[1:])) 
['Q1.2', 'Q1.3', 'Q6.1'] 
+0

Điều này làm việc cho các danh sách nói chung và tôi quen thuộc với nó. Làm thế nào để áp dụng nó vào một DataFrame gấu trúc? – pythOnometrist

+1

Không chắc chắn, tôi thừa nhận câu trả lời của tôi không dành riêng cho thư viện này. – tweet

186

Bạn cũng có thể làm một cách ngắn gọn hơn:

df.sort_index(axis=1)

Sửa:

Đảm bảo bạn giữ giá trị

df = df.sort_index(axis=1)

Hoặc làm điều đó tại chỗ

df.sort_index(axis=1, inplace=True)

+2

hãy nhớ thực hiện 'df = df.sort_index (trục = 1)', trên @multigoodverse – GoJian

+5

hoặc sửa đổi 'df' tại chỗ bằng' df.sort_index (trục = 1, inplace = True) ' – Jakub

+1

Điều này phải là # 1 –

16

Tweet's answer thể được truyền cho câu trả lời BrenBarn của trên với

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1) 

Vì vậy, ví dụ của bạn, nói:

vals = randint(low=16, high=80, size=25).reshape(5,5) 
cols = ['Q1.3', 'Q6.1', 'Q1.2', 'Q9.1', 'Q10.2'] 
data = DataFrame(vals, columns = cols) 

Bạn nhận:

data 

    Q1.3 Q6.1 Q1.2 Q9.1 Q10.2 
0 73  29  63  51  72 
1 61  29  32  68  57 
2 36  49  76  18  37 
3 63  61  51  30  31 
4 36  66  71  24  77 

Sau đó làm:

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1) 

kết quả là:

data 


    Q1.2 Q1.3 Q6.1 Q9.1 Q10.2 
0 2  0  1  3  4 
1 7  5  6  8  9 
2 2  0  1  3  4 
3 2  0  1  3  4 
4 2  0  1  3  4 
20

Bạn chỉ có thể làm:

 
df[sorted(df.columns)] 
+1

Tôi nhận được đối tượng "DataFrame" không thể gọi "cho điều này. Phiên bản: gấu trúc 0,14. – multigoodverse

13

Đừng quên thêm "inplace = True" vào câu trả lời của Wes hoặc đặt kết quả vào một DataFrame mới.

df.sort_index(axis=1, inplace=True) 
3

Phương pháp nhanh nhất là:

df.sort_index(axis=1) 

Hãy nhận biết rằng điều này tạo ra một trường hợp mới.Vì vậy, bạn cần phải lưu trữ kết quả trong một biến mới:

sortedDf=df.sort_index(axis=1) 
-1
print df.sort_index(by='Frequency',ascending=False) 

nơi bởi là tên của cột, nếu bạn muốn sắp xếp các dữ liệu dựa trên cột

9

Nếu bạn cần một tùy ý trình tự thay vì chuỗi được sắp xếp, bạn có thể làm:

sequence = ['Q1.1','Q1.2','Q1.3',.....'Q6.1',......] 
your_dataframe = your_dataframe.reindex(columns=sequence) 

Tôi đã thử nghiệm điều này trong 2.7.10 và nó đã làm việc cho tôi.

5

Đối với nhiều cột, Bạn có thể đặt cột đặt những gì bạn muốn:

#['A', 'B', 'C'] <-this is your columns order 
df = df[['C', 'B', 'A']] 

Ví dụ này cho thấy phân loại và slicing cột:

d = {'col1':[1, 2, 3], 'col2':[4, 5, 6], 'col3':[7, 8, 9], 'col4':[17, 18, 19]} 
df = pandas.DataFrame(d) 

Bạn nhận:

col1 col2 col3 col4 
1  4  7 17 
2  5  8 18 
3  6  9 19 

Sau đó, làm:

df = df[['col3', 'col2', 'col1']] 

Hệ quả là:

col3 col2 col1 
7  4  1 
8  5  2 
9  6  3  
0

Một use-case là bạn đã được đặt tên (một số) các cột của bạn với một số tiền tố, và bạn muốn các cột được sắp xếp với những tiền tố tất cả cùng nhau và trong một số thứ tự đặc biệt (không phải chữ cái).

Ví dụ: bạn có thể bắt đầu tất cả các tính năng của mình bằng Ft_, nhãn với Lbl_, v.v ... và trước tiên bạn muốn tất cả các cột chưa được cố định trước đó. Bạn có thể làm điều này với các chức năng sau (Tôi sẽ lưu ý một vấn đề hiệu quả có thể sử dụng sum để giảm danh sách, nhưng đây không phải là một vấn đề, trừ khi bạn có một LOT của cột, mà tôi không):

def sortedcols(df, groups = ['Ft_', 'Lbl_']): 
    return df[ sum([list(filter(re.compile(r).search, list(df.columns).copy())) for r in (lambda l: ['^(?!(%s))' % '|'.join(l)] + ['^%s' % i for i in l ])(groups) ], []) ] 
Các vấn đề liên quan