74

MultiIndex Series があるとしましょうs:

>>> s
     values
a b
1 2  0.1 
3 6  0.3
4 4  0.7

行のインデックスを使用する関数を適用したい:

def f(x):
   # conditions or computations using the indexes
   if x.index[0] and ...: 
   other = sum(x.index) + ...
   return something

そのような機能のためにどのようにすればよいs.apply(f)ですか?この種の操作を行うための推奨される方法は何ですか? この関数を各行に適用した結果の値と同じ MultiIndex を使用して、新しい Series を取得することを期待しています。

4

6 に答える 6

50

applyインデックスにアクセスできるとは思いません。ご覧のとおり、各行を Series ではなく 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'>

この制限を回避するには、インデックスを列にプロモートし、関数を適用して、元のインデックスで Series を再作成します。

Series(s.reset_index().apply(f, axis=1).values, index=s.index)

他のアプローチはs.get_level_values、私の意見ではしばしば少し醜くなるかs.iterrows()、遅くなる可能性が高い を使用する可能性があります-おそらく正確に何が行われるかによって異なりfます。

于 2013-08-19T14:52:38.490 に答える
3

ここよりも使用する方が速い場合があります。whereapply

In [11]: s = pd.Series([1., 2., 3.], index=['a' ,'b', 'c'])

In [12]: s.where(s.index != 'a', 5)
Out[12]: 
a    5
b    2
c    3
dtype: float64

また、numpy スタイルのロジック/関数を任意のパーツに使用できます。

In [13]: (2 * s + 1).where((s.index == 'b') | (s.index == 'c'), -s)
Out[13]: 
a   -1
b    5
c    7
dtype: float64

In [14]: (2 * s + 1).where(s.index != 'a', -s)
Out[14]: 
a   -1
b    5
c    7
dtype: float64

速度をテストすることをお勧めします (適用に対する効率は関数に依存するため)。ただし、applys の方が読みやすいことがわかります...

于 2013-08-19T15:51:26.827 に答える
0

Series.apply() の代わりに DataFrame.apply() を使用すると、関数内の引数として行全体にアクセスできます。

def f1(row):
    if row['I'] < 0.5:
        return 0
    else:
        return 1

def f2(row):
    if row['N1']==1:
        return 0
    else:
        return 1

import pandas as pd
import numpy as np
df4 = pd.DataFrame(np.random.rand(6,1), columns=list('I'))
df4['N1']=df4.apply(f1, axis=1)
df4['N2']=df4.apply(f2, axis=1)
于 2015-06-16T23:22:00.750 に答える