Ale*_*erg 62 python indexing dataframe pandas
将函数应用于Pandas索引的最佳方法是什么DataFrame?目前我正在使用这种冗长的方法:
pd.DataFrame({"Month": df.reset_index().Date.apply(foo)})
Run Code Online (Sandbox Code Playgroud)
其中Date是索引foo的名称,是我正在应用的函数的名称.
fir*_*ynx 79
正如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
Run Code Online (Sandbox Code Playgroud)
正如@OP所指出的那样.该df.index.map(str.lower)调用返回一个numpy数组.这是因为数据框指数是基于numpy的阵列,而不是系列.
将索引编入系列的唯一方法是从中创建一个系列.
pd.Series(df.index.map(str.lower))
Run Code Online (Sandbox Code Playgroud)
在Index类现在的子类StringAccessorMixin,这意味着你可以做以上操作如下
df.index.str.lower()
Run Code Online (Sandbox Code Playgroud)
这仍然会产生一个Index对象,而不是一个Series.
小智 7
假设您希望通过将函数"foo"应用于索引来在当前DataFrame中创建列.你可以写......
df['Month'] = df.index.map(foo)
Run Code Online (Sandbox Code Playgroud)
要单独生成系列,你可以做...
pd.Series({x: foo(x) for x in foo.index})
Run Code Online (Sandbox Code Playgroud)
您可以使用其to_series()方法转换索引,然后根据需要转换为apply或map。
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
Run Code Online (Sandbox Code Playgroud)
以上所有内容都可以直接分配给新的或现有的列df:
df["column"] = ret
Run Code Online (Sandbox Code Playgroud)
只是为了完整性:pd.Index.map,pd.Series.map并且pd.Series.apply都按元素操作。我经常使用或map表示的查找。更通用,因为您可以将任何函数与附加或. 和之间的区别在此 SO 线程中进一步讨论。不知道为什么被省略了。dictspd.Seriesapplyargskwargsapplymappd.Index.apply
很多答案都将索引作为数组返回,这会丢失有关索引名称等的信息(尽管您可以这样做pd.Series(index.map(myfunc), name=index.name))。它也不适用于多重索引。
我处理这个问题的方法是使用“重命名”:
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
Run Code Online (Sandbox Code Playgroud)
唯一的技巧是你的索引需要有不同的多索引级别的唯一标签,但也许比我更聪明的人知道如何解决这个问题。就我的目的而言,这在 95% 的情况下都有效。