Restablecer los niveles MultiIndex de una columna

¿Hay una forma más corta de eliminar una columna del nivel MultiIndex (en mi caso, basic_amt ), excepto la transposición dos veces?

 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 

Otra solución es usar MultiIndex.droplevel con rename_axis (nuevo en pandas 0.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') 

Si es necesario, ambos nombres de columna usan la list comprensión:

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

¿Qué hay de simplemente reasignar df.columns :

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

Por ejemplo:

 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 

Antes de:

 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 

Después:

 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 

Zip niveles juntos

Aquí hay una solución alternativa que comprime los niveles y los une con un guión bajo.

Derivado de la respuesta anterior, y esto era lo que quería hacer cuando encontré esta respuesta. Pensé que compartiría incluso si no responde a la pregunta anterior.

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

da

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

Solo configura esto como las columnas

 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