¿Cómo puedo reordenar las columnas de marcos de datos de múltiples índices en un nivel específico?

Tengo un DataFrame multi-indexado con nombres adjuntos a los niveles de columna. Me gustaría poder mezclar fácilmente las columnas para que coincidan con el orden especificado por el usuario. Dado que esto no se ha concretado, no puedo usar esta solución recomendada y ordenarlos correctamente en el momento de la creación.

Tengo una tabla de datos que se parece (algo) a

 Experiment BASE IWWGCW IWWGDW Lead Time 24 48 24 48 24 48 2010-11-27 12:00:00 0.997 0.991 0.998 0.990 0.998 0.990 2010-11-28 12:00:00 0.998 0.987 0.997 0.990 0.997 0.990 2010-11-29 12:00:00 0.997 0.992 0.997 0.992 0.997 0.992 2010-11-30 12:00:00 0.997 0.987 0.997 0.987 0.997 0.987 2010-12-01 12:00:00 0.996 0.986 0.996 0.986 0.996 0.986 

Quiero tomar una lista como ['IWWGCW', 'IWWGDW', 'BASE'] y reordenar esto para que sea:

 Experiment IWWGCW IWWGDW BASE Lead Time 24 48 24 48 24 48 2010-11-27 12:00:00 0.998 0.990 0.998 0.990 0.997 0.991 2010-11-28 12:00:00 0.997 0.990 0.997 0.990 0.998 0.987 2010-11-29 12:00:00 0.997 0.992 0.997 0.992 0.997 0.992 2010-11-30 12:00:00 0.997 0.987 0.997 0.987 0.997 0.987 2010-12-01 12:00:00 0.996 0.986 0.996 0.986 0.996 0.986 

con la advertencia de que no siempre sé en qué nivel será “Experimento”. Lo intenté (donde df es el marco multi-indexado que se muestra arriba)

 df2 = df.reindex_axis(['IWWGCW', 'IWWGDW', 'BASE'], axis=1, level='Experiment') 

pero eso no pareció funcionar; se completó con éxito, pero el DataFrame que se devolvió mantuvo su orden de columna sin cambios.

Mi solución es tener una función como:

 def reorder_columns(frame, column_name, new_order): """Shuffle the specified columns of the frame to match new_order.""" index_level = frame.columns.names.index(column_name) new_position = lambda t: new_order.index(t[index_level]) new_index = sorted(frame.columns, key=new_position) new_frame = frame.reindex_axis(new_index, axis=1) return new_frame 

donde reorder_columns(df, 'Experiment', ['IWWGCW', 'IWWGDW', 'BASE']) hace lo que espero pero siento que estoy haciendo un trabajo extra. ¿Hay alguna forma más fácil de hacer esto?

No sé nada de la mano. Creó un ticket de mejora al respecto:

http://github.com/pydata/pandas/issues/1864

Hay una forma muy simple: simplemente cree un nuevo dataframe basado en el original, con el orden correcto de las columnas de múltiples índices:

 multi_tuples = [('IWWGCW',24), ('IWWGCW',48), ('IWWGDW',24), ('IWWGDW',48) , ('BASE',24), ('BASE',48)] multi_cols = pd.MultiIndex.from_tuples(multi_tuples, names=['Experiment', 'Lead Time']) df_ordered_multi_cols = pd.DataFrame(df_ori, columns=multi_cols)