2017-09-23 17 views
1

私はいくつかの列を含むDataFrame、dfを持っています。 dfの値の一部はNaNです。私はそれぞれのNaNを、指定された列の他の値からランダムにサンプリングして選択した有効な値に置き換えたいと思います。私は時間の4時間の2/3と1/3 7でdf[work][2]を交換したいと思いますパンダ:列値のランダムサンプリングを使用したNaNの置換

df[work] = [4, 7, NaN, 4]

:場合例えば

、。私はより良い、よりPython的な方法があります考えている

def resample_fillna(df): 
    for col in df.columns: 
     # get series consisting of non-NaN values 
     valid_series = df[col].dropna() 
     nan_indices = np.argwhere(np.isnan(df[col])) 
     for nan_index in nan_indices: 
      df[col][nan_index] = valid_series.sample(n=1) 

は、ここに私の試みです。何かご意見は?

ありがとうございます!

+0

すべての欠損値を同じランダム値または異なるランダム値で置き換えますか? –

答えて

2

いくつかの偽のデータを作成し、同じ列の他の値をランダムに入力してみましょう。

np.random.seed(123) 
data = np.random.randint(0, 10, (10,5)) 
df = pd.DataFrame(data, columns=list('abcde')) 
df = df.where(df > 2) 
df 

    a b c d e 
0 NaN NaN 6.0 NaN 3.0 
1 9.0 6.0 NaN NaN NaN 
2 9.0 NaN NaN 9.0 3.0 
3 4.0 NaN NaN 4.0 NaN 
4 7.0 3.0 NaN 4.0 7.0 
5 NaN 4.0 8.0 NaN 7.0 
6 9.0 3.0 4.0 6.0 NaN 
7 5.0 6.0 NaN NaN 8.0 
8 3.0 5.0 NaN NaN 6.0 
9 NaN 4.0 4.0 6.0 3.0 

非欠損値から交換してapplyとサンプルと各カラムを通して今、私達ができるループ。

df.apply(lambda x: np.where(x.isnull(), x.dropna().sample(len(x), replace=True), x)) 

    a b c d e 
0 5.0 3.0 6.0 6.0 3.0 
1 9.0 6.0 4.0 9.0 7.0 
2 9.0 5.0 8.0 9.0 3.0 
3 4.0 3.0 8.0 4.0 6.0 
4 7.0 3.0 4.0 4.0 7.0 
5 9.0 4.0 8.0 6.0 7.0 
6 9.0 3.0 4.0 6.0 3.0 
7 5.0 6.0 4.0 4.0 8.0 
8 3.0 5.0 4.0 4.0 6.0 
9 9.0 4.0 4.0 6.0 3.0 
+0

'n = 1'を実行するのではなく、なぜ' sample'の中で 'len(x)'を使うのですか? – bclayman

+2

@bclaymanの場合、n = 1をサンプリングします。これは、あなたのセットから1つの値を取り出し、各nanに対して1回サンプリングする代わりに、すべてのNaNに1つの値を置きます。たとえば、Tedによる設定では、n = len(x)ではなくn = 1の場合、最初の列は3つのNaNすべてに対して同じ値を取得します。 –

関連する問題