访问pandas.Series.apply中的索引

ely*_*ase 48 python pandas

让我们说我有一个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.

  • +1用于摆脱`MultiIndex`.虽然这些偶尔有用,但我发现自己越来越多地把我的索引变成了列. (3认同)

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)

  • 这应该是答案,采用`x.name`是解决问题的最干净,最灵活的方法。 (2认同)

neh*_*ehz 5

转换DataFrame并沿行应用。您可以按访问索引x.namex也是Series具有1值的现在

s.to_frame(0).apply(f, axis=1)[0]
Run Code Online (Sandbox Code Playgroud)