2015-10-17 24 views
7

Trong Pandas 0,17 Tôi cố gắng sắp xếp theo một cột cụ thể trong khi duy trì chỉ mục phân cấp (A và B). B là một số chạy được tạo khi thiết lập khung dữ liệu thông qua nối. Dữ liệu của tôi trông như thế này:Python Pandas phân loại theo multiindex và cột

  C  D 
A B 
bar one shiny 10 
    two dull 5 
    three glossy 8 
foo one dull 3 
    two shiny 9 
    three matt 12 

Đây là những gì tôi cần:

  C  D 
A B 
bar two dull 5 
    three glossy 8 
    one shiny 10 
foo one dull 3 
    three matt 12 
    two shiny 9 

Dưới đây là đoạn code tôi đang sử dụng và kết quả. Lưu ý: Pandas 0,17 cảnh báo rằng dataframe.sort sẽ không được chấp nhận.

df.sort_values(by="C", ascending=True) 
      C  D 
A B 
bar two dull 5 
foo one dull 3 
bar three glossy 8 
foo three matt 12 
bar one shiny 10 
foo two shiny 9 

Thêm .groupby tạo ra kết quả tương tự:

df.sort_values(by="C", ascending=True).groupby(axis=0, level=0, as_index=True) 

Tương tự như vậy, việc chuyển đổi sang sắp xếp các chỉ số đầu tiên, và sau đó groupby cột là không hiệu quả:

df.sort_index(axis=0, level=0, as_index=True).groupby(C, as_index=True) 

Tôi không chắc chắn về reindexing tôi cần phải giữ chỉ số đầu tiên A, chỉ số thứ hai B có thể được gán lại, nhưng không phải. Nó sẽ làm tôi ngạc nhiên nếu không có giải pháp dễ dàng; Tôi đoán tôi không tìm thấy nó. Mọi đề xuất đều được đánh giá cao.


Chỉnh sửa: Trong khi đó Anh đã đánh rơi chỉ số B thứ hai, bố trí chỉ số A đầu tiên trở thành một cột thay vì một chỉ số được sắp xếp nhiều cột, sau đó tái lập chỉ mục:

df.index = df.index.droplevel(1) 
df.reset_index(level=0, inplace=True) 
df_sorted = df.sort_values(["A", "C"], ascending=[1,1]) #A is a column here, not an index. 
df_reindexed = df_sorted.set_index("A") 

Vẫn còn rất tiết.

Trả lời

6

Cảm thấy như có thể là một cách tốt hơn, nhưng đây là một cách tiếp cận:

In [163]: def sorter(sub_df): 
    ...:  sub_df = sub_df.sort_values('C') 
    ...:  sub_df.index = sub_df.index.droplevel(0) 
    ...:  return sub_df 

In [164]: df.groupby(level='A').apply(sorter) 
Out[164]: 
       C D 
A B     
bar two  dull 5 
    three glossy 8 
    one  shiny 10 
foo one  dull 3 
    three matt 12 
    two  shiny 9 
+0

Cách tiếp cận của bạn tiên tiến hơn giải pháp trung gian của tôi, nhưng tôi đồng ý rằng cần có cách tốt hơn. – raummensch

1

Dựa trên mã chrisb của:

Lưu ý rằng trong trường hợp của tôi, đó là một dòng không phải là một DataFrame,

s.groupby(level='A', group_keys=False).apply(lambda x: x.sort_values(ascending=False)) 
Các vấn đề liên quan