让我们说我有一个MultiIndex系列s
:
>>> s
values
a b
1 2 0.1
3 6 0.3
4 4 0.7
Run Code Online (Sandbox Code Playgroud)
我想应用一个使用行索引的函数:
def f(x):
# conditions or computations using the indexes
if x.index[0] and ...:
other = sum(x.index) + ...
return something
Run Code Online (Sandbox Code Playgroud)
我怎么能做s.apply(f)
这样的功能?这种操作的推荐方法是什么?我期望获得一个新系列,其中每个行和相同的MultiIndex都应用了此函数产生的值.
Dan*_*lan 35
我不相信apply
有权访问该索引; 它将每一行视为一个numpy对象,而不是一个系列,你可以看到:
In [27]: s.apply(lambda x: type(x))
Out[27]:
a b
1 2 <type 'numpy.float64'>
3 6 <type 'numpy.float64'>
4 4 <type 'numpy.float64'>
Run Code Online (Sandbox Code Playgroud)
要解决此限制,请将索引提升为列,应用函数,然后使用原始索引重新创建Series.
Series(s.reset_index().apply(f, axis=1).values, index=s.index)
Run Code Online (Sandbox Code Playgroud)
可能会使用其他方法s.get_level_values
,在我看来这通常会有点难看,或者s.iterrows()
可能会更慢 - 可能取决于究竟是什么f
.
Jef*_*eff 11
使它成为一个框架,如果你想要返回标量(所以结果是一系列)
建立
In [11]: s = Series([1,2,3],dtype='float64',index=['a','b','c'])
In [12]: s
Out[12]:
a 1
b 2
c 3
dtype: float64
Run Code Online (Sandbox Code Playgroud)
打印功能
In [13]: def f(x):
print type(x), x
return x
....:
In [14]: pd.DataFrame(s).apply(f)
<class 'pandas.core.series.Series'> a 1
b 2
c 3
Name: 0, dtype: float64
<class 'pandas.core.series.Series'> a 1
b 2
c 3
Name: 0, dtype: float64
Out[14]:
0
a 1
b 2
c 3
Run Code Online (Sandbox Code Playgroud)
既然你可以在这里返回任何内容,只需返回标量(通过name
属性访问索引)
In [15]: pd.DataFrame(s).apply(lambda x: 5 if x.name == 'a' else x[0] ,1)
Out[15]:
a 5
b 2
c 3
dtype: float64
Run Code Online (Sandbox Code Playgroud)
转换DataFrame
并沿行应用。您可以按访问索引x.name
。x
也是Series
具有1值的现在
s.to_frame(0).apply(f, axis=1)[0]
Run Code Online (Sandbox Code Playgroud)