Aplicar la función en el índice DataFrame

¿Cuál es la mejor manera de aplicar una función sobre el índice de un DataFrame Pandas? Actualmente estoy usando este enfoque detallado:

 pd.DataFrame({"Month": df.reset_index().Date.apply(foo)}) 

donde Date es el nombre del índice y foo es el nombre de la función que estoy aplicando.

Como ya lo sugirió HYRY en los comentarios, Series.map es el camino a seguir aquí. Solo establece el índice a la serie resultante.

Ejemplo simple:

 df = pd.DataFrame({'d': [1, 2, 3]}, index=['FOO', 'BAR', 'BAZ']) df d FOO 1 BAR 2 BAZ 3 df.index = df.index.map(str.lower) df d foo 1 bar 2 baz 3 

Índice! = Serie

Como señalado por @OP. la df.index.map(str.lower) devuelve una matriz numpy. Esto se debe a que los índices de dataframe se basan en matrices numpy, no en series.

La única forma de convertir el índice en una serie es crear una serie a partir de ella.

 pd.Series(df.index.map(str.lower)) 

Advertencia

La clase de Index ahora subclasifica el StringAccessorMixin , lo que significa que puede hacer la operación anterior de la siguiente manera

 df.index.str.lower() 

Esto todavía produce un objeto de índice, no una serie.

Suponiendo que desea hacer una columna en su DataFrame actual aplicando su función “foo” al índice. Podrías escribir …

 df['Month'] = df.index.map(foo) 

Para generar la serie solo podrías hacer …

 pd.Series({x: foo(x) for x in foo.index}) 

Muchas respuestas están devolviendo el Índice como una matriz, lo que pierde información sobre el nombre del índice, etc. (aunque podría hacer pd.Series(index.map(myfunc), name=index.name) ). Tampoco funcionará para un MultiIndex.

La forma en que trabajé con esto es usar “renombrar”:

 mix = pd.MultiIndex.from_tuples([[1, 'hi'], [2, 'there'], [3, 'dude']], names=['num', 'name']) data = np.random.randn(3) df = pd.Series(data, index=mix) print(df) num name 1 hi 1.249914 2 there -0.414358 3 dude 0.987852 dtype: float64 # Define a few dictionaries to denote the mapping rename_dict = {i: i*100 for i in df.index.get_level_values('num')} rename_dict.update({i: i+'_yeah!' for i in df.index.get_level_values('name')}) df = df.rename(index=rename_dict) print(df) num name 100 hi_yeah! 1.249914 200 there_yeah! -0.414358 300 dude_yeah! 0.987852 dtype: float64 

El único truco con esto es que su índice debe tener tags exclusivas para diferentes niveles de índices múltiples, pero tal vez alguien más inteligente que yo sepa cómo hacerlo. Para mis propósitos esto funciona el 95% del tiempo.