Tengo un marco de datos indexado múltiple, pero quiero mantener solo dos columnas por nivel 1, para cada una de las variables de nivel 0 (es decir, columnas 'uno' y 'dos'). Puedo subdividirlos por separado, pero me gustaría hacerlo juntos para poder mantener los valores uno al lado del otro
Aquí está el marco de datos
index = pd.MultiIndex.from_tuples(list(zip(*[['bar1', 'foo1', 'bar1', 'foo2','bar3','foo3'], ['one','two','three','two','one','four']]))) df = pd.DataFrame(np.random.randn(2, 6), columns=index)Esta es la forma de crear subconjuntos para una columna en el nivel 1
df.iloc[:, df.columns.get_level_values(1)== 'one'] # or df.xs('one', level=1, axis=1) # but adding two columns within either command will not work eg df.xs(('one','two), level=1, axis=1)Esta sería la salida esperada
bar1 foo1 foo2 bar3 one two two one 0 -0.508272 -0.195379 0.865563 2.002205 1 -0.771565 1.360479 1.900931 -1.589277Aquí hay una forma de usar pd.IndexSlice :
idnx = pd.IndexSlice[:, ['one', 'two']] df.loc[:, idnx]Producción:
bar1 bar3 foo1 foo2 one one two two 0 0.589999 0.261224 -0.106588 -2.309628 1 0.646201 -0.491110 0.430724 1.027424 Otra forma de usar un argumento poco conocido, axis , de pd.DataFrame.loc :
df.loc(axis=1)[:, ['one', 'two']]Producción:
bar1 bar3 foo1 foo2 one one two two 0 0.589999 0.261224 -0.106588 -2.309628 1 0.646201 -0.491110 0.430724 1.027424NOTA: Este argumento no aparece en la API documentada para pd.DataFrame.loc, pero se hace referencia en la Guía del usuario en la sección MultiIndex/Indización avanzada en el párrafo Uso de segmentaciones sobre el punto medio con un ejemplo.
Puede reindex y especificar el level .
df.reindex(['one', 'two'], axis=1, level=1) bar1 foo1 foo2 bar3 one two two one 0 0.276056 1.956400 -1.495128 1.582220 1 -0.383178 1.159138 -1.646173 0.821942Podemos usar Index.isin en un nivel específico para crear un índice booleano y seleccionar con loc :
df.loc[:, df.columns.isin(['one', 'two'], level=1)] df .:
bar1 foo1 foo2 bar3 one two two one 0 0.042062 -0.233098 0.620974 0.330957 1 0.524495 -0.394930 0.572631 0.499279Verifique los get_level_values a la antigua
out = df.loc[:,df.columns.get_level_values(1).isin(['one','two'])] Out[454]: bar1 foo1 foo2 bar3 one two two one 0 -0.705540 -1.175132 -0.572076 -1.549703 1 0.277905 1.789925 1.104225 0.104453