2013-01-07 31 views
18

Có cách nào ngắn hơn để giảm mức MultiIndex cột (trong trường hợp của tôi là basic_amt) ngoại trừ việc chuyển nó hai lần?Đặt lại một cột Các mức MultiIndex

In [704]: test 
Out[704]: 
      basic_amt    
Faculty   NSW QLD VIC All 
All    1 1 2 4 
Full Time   0 1 0 1 
Part Time   1 0 2 3 

In [705]: test.reset_index(level=0, drop=True) 
Out[705]: 
     basic_amt    
Faculty  NSW QLD VIC All 
0    1 1 2 4 
1    0 1 0 1 
2    1 0 2 3 

In [711]: test.transpose().reset_index(level=0, drop=True).transpose() 
Out[711]: 
Faculty NSW QLD VIC All 
All   1 1 2 4 
Full Time 0 1 0 1 
Part Time 1 0 2 3 

Trả lời

10

giải pháp khác là sử dụng sử dụng MultiIndex.droplevel với rename_axis (mới trong pandas0.18.0):

import pandas as pd 

cols = pd.MultiIndex.from_arrays([['basic_amt']*4, 
            ['NSW','QLD','VIC','All']], 
            names = [None, 'Faculty']) 
idx = pd.Index(['All', 'Full Time', 'Part Time']) 

df = pd.DataFrame([(1,1,2,4), 
        (0,1,0,1), 
        (1,0,2,3)], index = idx, columns=cols) 

print (df) 
      basic_amt    
Faculty   NSW QLD VIC All 
All    1 1 2 4 
Full Time   0 1 0 1 
Part Time   1 0 2 3 

df.columns = df.columns.droplevel(0) 
#pandas 0.18.0 and higher 
df = df.rename_axis(None, axis=1) 
#pandas bellow 0.18.0 
#df.columns.name = None 

print (df) 
      NSW QLD VIC All 
All   1 1 2 4 
Full Time 0 1 0 1 
Part Time 1 0 2 3 

print (df.columns) 
Index(['NSW', 'QLD', 'VIC', 'All'], dtype='object') 

Nếu cần cả hai cột tên sử dụng list hiểu:

df.columns = ['_'.join(col) for col in df.columns] 
print (df) 
      basic_amt_NSW basic_amt_QLD basic_amt_VIC basic_amt_All 
All     1    1    2    4 
Full Time    0    1    0    1 
Part Time    1    0    2    3 

print (df.columns) 
Index(['basic_amt_NSW', 'basic_amt_QLD', 'basic_amt_VIC', 'basic_amt_All'], dtype='object') 
+1

Cũng cần lưu ý: Nếu bạn đã làm phẳng nhiều chỉ mục bằng cách sử dụng dấu '_' làm dấu phân cách và muốn tạo lại nó, bạn có thể thực hiện 'my_tuples = [i.split (" _ ") cho i trong df.columns]' và sau đó là 'pd.MultiIndex.from_tuples (my_tuples)' – RobinL

11

Làm thế nào về đơn giản reassigning df.columns:

levels = df.columns.levels 
labels = df.columns.labels 
df.columns = levels[1][labels[1]] 

Ví dụ:

import pandas as pd 

columns = pd.MultiIndex.from_arrays([['basic_amt']*4, 
            ['NSW','QLD','VIC','All']]) 
index = pd.Index(['All', 'Full Time', 'Part Time'], name = 'Faculty') 
df = pd.DataFrame([(1,1,2,4), 
        (0,01,0,1), 
        (1,0,2,3)]) 
df.columns = columns 
df.index = index 

Trước:

print(df) 

      basic_amt    
       NSW QLD VIC All 
Faculty        
All    1 1 2 4 
Full Time   0 1 0 1 
Part Time   1 0 2 3 

Sau:

levels = df.columns.levels 
labels = df.columns.labels 
df.columns = levels[1][labels[1]] 
print(df) 

      NSW QLD VIC All 
Faculty      
All   1 1 2 4 
Full Time 0 1 0 1 
Part Time 1 0 2 3 
+1

Điều đó sẽ không hoạt động nếu một người có nhiều hơn một loại trong MultiIndex level = 0, và điều này (theo ví dụ của bạn) cũng messes thứ tự của cột. Bạn có thể nghĩ ra giải pháp tổng quát hơn (và bằng chứng không thành công) không? – dmvianna

+0

Tôi chỉ thử nó và có vẻ như công việc tìm cho tôi. Bạn có thể đưa ra một ví dụ về loại DataFrame mà bạn đang làm việc không? – unutbu

+0

df = pd.DataFrame (np.array (np.mat ('0 1 0 1; 1 0 2 3; 1 1 2 4'))) – dmvianna

1

mức Zip cùng

Dưới đây là một giải pháp thay thế mà kéo khóa các cấp với nhau và tham gia chúng với dấu gạch dưới.

Có nguồn gốc từ câu trả lời ở trên và đây là những gì tôi muốn làm khi tôi tìm thấy câu trả lời này. Tôi nghĩ rằng tôi sẽ chia sẻ ngay cả khi nó không trả lời chính xác câu hỏi trên.

["_".join(pair) for pair in df.columns] 

cho

['basic_amt_NSW', 'basic_amt_QLD', 'basic_amt_VIC', 'basic_amt_All'] 

Chỉ cần thiết lập này như một cột

df.columns = ["_".join(pair) for pair in df.columns] 

      basic_amt_NSW basic_amt_QLD basic_amt_VIC basic_amt_All 
Faculty                
All     1    1    2    4 
Full Time    0    1    0    1 
Part Time    1    0    2    3 
Các vấn đề liên quan