在DataFrame索引上应用函数

在Pandas DataFrame的索引上应用函数的最佳方法是什么? 目前我正在使用这种详细的方法:

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

其中Date是索引的名称, foo是我正在应用的函数的名称。

正如HYRY在评论中已经提出的那样, Series.map是要走的路。 只需将索引设置为最终的系列。

简单的例子:

 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 

索引!=系列

正如@OP所指出的那样。 df.index.map(str.lower)调用返回一个numpy数组。 这是因为dataframe索引基于numpy数组,而不是Series。

将索引编制为Series的唯一方法是从中创build一个Series。

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

警告

Index类现在是StringAccessorMixin子类,这意味着您可以按照以下方式执行上述操作

 df.index.str.lower() 

这仍然会产生一个Index对象,而不是一个Series。

假设你想通过将你的函数“foo”应用到索引来创build你当前的DataFrame中的一列。 你可以写…

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

要单独生成系列,您可以改为…

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

很多答案都将索引作为数组返回,这会丢失有关索引名称等信息(尽pipe您可以执行pd.Series(index.map(myfunc), name=index.name) )。 它也不适用于MultiIndex。

我与之合作的方式是使用“重命名”:

 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 

与此唯一的技巧是您的索引需要有不同的multiindex水平不同的唯一标签,但也许有人比我更聪明知道如何解决这个问题。 为我的目的,这95%的时间工作。