2013-01-07 18 views
18

Czy istnieje krótszy sposób upuszczania kolumnowego poziomu MultiIndex (w moim przypadku basic_amt) z wyjątkiem przeniesienia go dwukrotnie?Resetowanie kolumn Poziomy 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 

Odpowiedz

10

Innym rozwiązaniem jest wykorzystanie wykorzystanie MultiIndex.droplevel z rename_axis (nowość w 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') 

Jeśli potrzebują zarówno nazwy kolumn używać list zrozumieniem:

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

Należy również pamiętać: Jeśli spłaszczyłeś multi-index używając '_' jako ogranicznika i chcesz go odtworzyć, możesz zrobić 'my_tuples = [i.split (" _ ") dla i in df.columns]' a następnie 'pd.MultiIndex.from_tuples (my_tuples)' – RobinL

11

Jak o prostu realokacja df.columns:

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

Na przykład:

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 

Przed:

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 

Po:

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

to nie zadziała, jeśli ma więcej niż jedną kategorię w poziomie MultiIndex = 0, a to (jak na swoim przykładzie) również bałagan kolejność kolumn. Czy możesz wymyślić bardziej ogólne (i odporne na awarie) rozwiązanie? – dmvianna

+0

Po prostu to wypróbowałem i wygląda na to, że znalazłem to dla mnie. Czy możesz podać przykład rodzaju DataFrame, z którym pracujesz? – unutbu

+0

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

1

poziomy Zip razem

Oto alternatywne rozwiązanie, które zamki poziomy razem i łączy je z podkreśleniem.

Pochodzi z powyższej odpowiedzi i właśnie to chciałem zrobić, gdy znalazłem tę odpowiedź. Pomyślałem, że podzielę się tym, nawet jeśli nie odpowie dokładnie na powyższe pytanie.

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

daje

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

Wystarczy ustawić to jako kolumn

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