2017-04-02 24 views
0

私はタイタニックのデータセットで遊んでいますが、AgeカラムのすべてのNaN/Null値にその中央値ベースPclass。ここで条件付きスライスに基づくパンダDataFrameのセルの変更

は、いくつかのデータです:

train 

PassengerId Pclass Age 
0 1 3 22 
1 2 1 35 
2 3 3 26 
3 4 1 35 
4 5 3 35 
5 6 1 NaN 
6 7 1 54 
7 8 3 2 
8 9 3 27 
9 10 2 14 
10 11 1 Nan 

は、ここで私はで終わるしたいものです。

PassengerId Pclass Age 
0 1 3 22 
1 2 1 35 
2 3 3 26 
3 4 1 35 
4 5 3 35 
5 6 1 35 
6 7 1 54 
7 8 3 2 
8 9 3 27 
9 10 2 14 
10 11 1 35 

私が思いついた最初のものは、これは - 簡潔さのために、私はPclassが2と3を含めるのではなく、1に等しいスライスを1つだけ含んでいます:

Pclass_1 = train['Pclass']==1 

train[Pclass_1]['Age'].fillna(train[train['Pclass']==1]['Age'].median(), inplace=True) 

私が理解する限り、このメソッドはtrainを編集するのではなく、ビューを作成します(これはコピーとどう違うのか、それともメモリの点では類似しているのか分かりません。可能であれば聞いてください)。私は特にトピックView vs Copy, How Do I Tell?のこのQ/Aが好きですが、私が探している洞察は含まれていません。

私はこの落とし穴を避けるために.locを使用する理由を知りました。しかし、私は構文の権利を得ることができません。

Pclass_1 = train.loc[:,['Pclass']==1] 

Pclass_1.Age.fillna(train[train['Pclass']==1]['Age'].median(),inplace=True) 

インデックスが失われています。これは明らかに存在しないFalseという名前の列を探します。私は連鎖インデックスなしでこれを行う方法を知らない。 train.loc[:,train['Pclass']==1]は例外IndexingError: Unalignable boolean Series key providedを返します。

+1

[Minimal、Complete、Verifiable](http://stackoverflow.com/help/mcve)の例、特にカットアンドペースト可能な例を提供する場合、これらの質問にはより迅速かつ大量に回答されます。例と予想されるデータ。 –

+0

私は実際のデータフレームからいくつかのサンプルデータを追加しました。 – prdctofchem

+0

@prdctofchem追加されたサンプルデータに基づいて回答を更新しました。 – Craig

答えて

0

ラインのこの部分では、

train.loc[:,['Pclass']==1] 

['Pclass'] == 1Falseを返し値1にリスト['Pclass']を比較しています。 .loc[]は、エラーの原因となる.loc[:,False]と評価されます。

私はあなたが意味を考える:

PCLASS 1.これは、エラーを修正し、それはまだあなたの「SettingWithCopyWarning」を与えるですべての行を選択し
train.loc[train['Pclass']==1] 

。ここ

EDIT 1

(古いコードを除去)

Pclassの中央値Ageを含むSeries を作成するtransformgroupbyを使用するアプローチです。 Seriesは、fillna()への引数として使用され、欠損値を中央値で置き換えます。このアプローチを使用すると、OPが最初に要求したものであるすべての旅客クラスを同時に修正します。

train['Age'].fillna(median_age, inplace=True) 

に置き換えることができます。注意すべき

Original: 
    PassengerId Pclass Age 
0    1  3 22.0 
1    2  1 35.0 
2    3  3 26.0 
3    4  1 35.0 
4    5  3 35.0 
5    6  1 NaN 
6    7  1 54.0 
7    8  3 2.0 
8    9  3 27.0 
9   10  2 14.0 
10   11  1 NaN 

NaNs replaced with median: 
    PassengerId Pclass Age 
0    1  3 22.0 
1    2  1 35.0 
2    3  3 26.0 
3    4  1 35.0 
4    5  3 35.0 
5    6  1 35.0 
6    7  1 54.0 
7    8  3 2.0 
8    9  3 27.0 
9   10  2 14.0 
10   11  1 35.0 

ことの一つは、inplace=Trueを使用してこの行が、ということです:解決策は、コードが生成Python-pandas Replace NA with the median or mean of a group in dataframe

import pandas as pd 
from io import StringIO 

tbl = """PassengerId Pclass Age 
0 1 3 22 
1 2 1 35 
2 3 3 26 
3 4 1 35 
4 5 3 35 
5 6 1 
6 7 1 54 
7 8 3 2 
8 9 3 27 
9 10 2 14 
10 11 1 
""" 

train = pd.read_table(StringIO(tbl), sep='\s+') 
print('Original:\n', train) 
median_age = train.groupby('Pclass')['Age'].transform('median') #median Ages for all groups 
train['Age'].fillna(median_age, inplace=True) 
print('\nNaNs replaced with median:\n', train) 

への回答から来ています代入を使用して.loc

train.loc[:,'Age'] = train['Age'].fillna(median_age) 
+0

複数のPclassのNaN値を持つデータセットにこれを適用すると、GroupBy dfがあるため、適切な場所に入力しますか?または、これを行う前にPclass値を一致させるために指定する必要はありますか?私は、単に.transform( 'median') 'の代わりに' .median() '集計メソッドを使用する方が私の場合にはより良い選択であるかどうか疑問に思っています。 – prdctofchem

+0

@prdctofchem 'groupby'は1つ以上のPclassのNaNに対して正しく動作します。私はちょうどテストを行い、これが動作するには 'transform()'が必要です。 'transform()'がなぜ重要であるかを見るためにコードを両方の方法でテストする必要があります。この回答が役に立ったら、それをアップして灰色のチェックマークをクリックして回答を受け入れてください。 – Craig

+0

'transform()'に関する追加情報:[Pandasの変換機能について](http://pbpython.com/pandas_transform.html) – prdctofchem

関連する問題