pandas 对DataFrame索引应用函数

tvz2xvvm  于 2023-05-12  发布在  其他
关注(0)|答案(4)|浏览(126)

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

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

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

vs91vp4v

vs91vp4v1#

正如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。
使索引成为系列的唯一方法是从它创建一个系列。

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

注意事项

现在,Index类继承了StringAccessorMixin,这意味着您可以按如下方式执行上述操作

df.index.str.lower()

这仍然会生成Index对象,而不是Series。

disho6za

disho6za2#

您可以使用to_series()方法转换索引,然后根据需要使用applymap

ret = df.index.map(foo)                # Returns pd.Index
ret = df.index.to_series().map(foo)    # Returns pd.Series
ret = df.index.to_series().apply(foo)  # Returns pd.Series

以上所有内容都可以直接分配给df的新列或现有列:

df["column"] = ret

只是为了完整:pd.Index.mappd.Series.mappd.Series.apply都按元素操作。我经常使用map来应用由dictspd.Series表示的查找。apply更通用,因为您可以传递任何函数沿着附加的argskwargsapplymap之间的差异在this SO thread中进一步讨论。我不知道为什么pd.Index.apply被省略了。

amrnrhlw

amrnrhlw3#

假设你想在你当前的DataFrame中创建一个列,通过对索引应用你的函数“foo”。你可以写…

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

要单独生成系列,您可以执行以下操作...

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

xkrw2x1b4#

很多答案都将Index作为数组返回,这会丢失有关索引名称等的信息(尽管您可以使用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

唯一的技巧是,你的索引需要有独特的标签b/w不同的多索引级别,但也许有人比我更聪明知道如何绕过这一点。在我看来,这在95%的时间里都是有效的。

相关问题