2016-09-07 9 views
1

を使ってパンダシリーズにカスタム関数を適用する私は思いは、私は一般的にこのようになりますサンプルデータフレームを持ってGROUPBYとpd.isnull

Age Class Sex 
0 15.0  1 1 
1 24.0  2 0 
2 13.0  2 0 
3 28.0  2 0 
4 29.0  1 1 
5 NaN  2 1 
6 34.0  1 0 
7 27.0  2 1 

「年齢」シリーズの各NaN値に、「クラス」と「性別」のグループを持つすべてのエントリの中央値を入力します。

df.groupby(['Class', 'Sex'])['Age'].median() 

とget::私はそうのように、これらの値にアクセスするとき

したがって、たとえば、

Class Sex 
    1  0  34.0 
      1  22.0 
    2  0  24.0 
      1  27.0 

私は自動的に27に現存NaN値を満たす関数を記述したいと思いますそれはClass値が2、Sex値が1のエントリの中央値です。

今私は:

特に、

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

しかし、非常によく似た構文がthis questionthis oneのための答えで使用されたので、地雷が動作しない理由を私はかなりよく分からない:

df['Age'] = df.groupby(['Class', 'Sex'])['Age'].apply(lambda x: x.median() if pd.isnull(x) else x) 

とは、次のエラーを取得しています後者はlambda関数でisnullメソッドも使用しているので、なぜ私がうまく動作しないのかがわかりませんが、それは問題ありません。

私もそうのようなfillnaメソッドを使用して試してみた:、私は同じ値を取得する他の方法に開いている

ValueError: Buffer dtype mismatch, expected 'Python object' but got 'long long' 

df['Age'] = df['Age'].fillna(df.groupby(['Class', 'Sex'])['Age'].median()) 

をしかし、次のエラーメッセージが表示されました別のfor-loopを使用せず、可能な限り簡潔にするために 'Apply'メソッドに渡すことなく、Pandasメソッドに完全に依存するものを好んでいます。

ありがとうございます。

答えて

2

一つのオプションAge列の中央値とnull値を置き換えるためにtransformを使用することです:

df['Age'] = df.groupby(['Class', 'Sex']).Age.transform(lambda col: col.where(col.notnull(), col.median())) 

df 

# Age Class Sex 
#0 15.0 1 1 
#1 24.0 2 0 
#2 13.0 3 0 
#3 28.0 2 0 
#4 29.0 1 1 
#5 27.0 2 1 
#6 34.0 3 0 
#7 27.0 2 1 

はまた代わりにwherereplaceメソッドを使用するにも動作します:

df['Age'] = df.groupby(['Class', 'Sex']).Age.transform(lambda col: col.replace(np.nan, col.median())) 
+0

ありがとうございました。簡単な質問:col.notnull()はnull値を置き換えるためcol.isnull()であるはずですか? –

+1

'pandas.Series.where()'は、条件が真である要素を保持し、条件がfalseの2番目の引数で値を置き換えます。これは 'replace()'メソッドとは異なります。詳細はhttp://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.where.html – Psidom

+0

の両方の方法で動作しますが、使用時にも動作することを追加します適用方法は、小さなパフォーマンスペナルティを伴いますが、です。そこで、if/elseステートメントをトリックを行ったwhere/replaceメソッドに置き換えていました。where()メソッドの時間は、19.5ms(適用)、15.2ms(変換)でした。 replace()メソッドの時間は、13.4ms(適用)、8.53(変換)でした。 –

関連する問題