大きなpandasデータ名声df
。かなりの数の欠落があります。行/列を削除することはオプションではありません。値もオプションではありません(したがって、pandas
および/またはscikit
による代入は、残念ながらトリックを行いません)。
fancyimpute
と呼ばれるきちんとしたパッケージのように見えるものに出会いました(あなたはそれを見つけることができます here )。しかし、私はそれにいくつかの問題があります。
ここに私がやることがあります:
_#the neccesary imports
import pandas as pd
import numpy as np
from fancyimpute import KNN
# df is my data frame with the missings. I keep only floats
df_numeric = = df.select_dtypes(include=[np.float])
# I now run fancyimpute KNN,
# it returns a np.array which I store as a pandas dataframe
df_filled = pd.DataFrame(KNN(3).complete(df_numeric))
_
ただし、_df_filled
_は、データフレームがいっぱいではなく、何らかの形で単一のベクトルです。代入を使用してデータフレームを取得するにはどうすればよいですか?
fancyimpute
には_numpay array
_が必要だと気付きました。したがって、as_matrix()
を使用して_df_numeric
_を配列に変換しました。
_# df is my data frame with the missings. I keep only floats
df_numeric = df.select_dtypes(include=[np.float]).as_matrix()
# I now run fancyimpute KNN,
# it returns a np.array which I store as a pandas dataframe
df_filled = pd.DataFrame(KNN(3).complete(df_numeric))
_
出力は、列ラベルが失われたデータフレームです。ラベルを取得する方法はありますか?
_df=pd.DataFrame(data=mice.complete(d), columns=d.columns, index=d.index)
_
Fancyimputeオブジェクト(マウスまたはKNN)の.complete()
メソッドによって返される_np.array
_は、pandasデータフレームのコンテンツ_(argument data=)
_として供給されますその列とインデックスは元のデータフレームと同じです。
コードの後に次の行を追加します。
df_filled.columns = df_numeric.columns
df_filled.index = df_numeric.index
私は派手な論争とパンダに不満を感じています。これは、再帰オーバーライドメソッドを使用した非常に基本的なラッパーです。データフレームを取り込み、出力します-列名はそのままです。これらの種類のラッパーは、パイプラインでうまく機能します。
from fancyimpute import SoftImpute
class SoftImputeDf(SoftImpute):
"""DataFrame Wrapper around SoftImpute"""
def __init__(self, shrinkage_value=None, convergence_threshold=0.001,
max_iters=100,max_rank=None,n_power_iterations=1,init_fill_method="zero",
min_value=None,max_value=None,normalizer=None,verbose=True):
super(SoftImputeDf, self).__init__(shrinkage_value=shrinkage_value,
convergence_threshold=convergence_threshold,
max_iters=max_iters,max_rank=max_rank,
n_power_iterations=n_power_iterations,
init_fill_method=init_fill_method,
min_value=min_value,max_value=max_value,
normalizer=normalizer,verbose=False)
def fit_transform(self, X, y=None):
assert isinstance(X, pd.DataFrame), "Must be pandas dframe"
for col in X.columns:
if X[col].isnull().sum() < 10:
X[col].fillna(0.0, inplace=True)
z = super(SoftImputeDf, self).fit_transform(X.values)
return pd.DataFrame(z, index=X.index, columns=X.columns)
@ jander081のアプローチに本当に感謝し、カテゴリー列の設定に対処するために少し拡張しました。カテゴリー列が設定解除され、トレーニング中にエラーが発生するという問題があったため、次のようにコードを変更しました。
from fancyimpute import SoftImpute
import pandas as pd
class SoftImputeDf(SoftImpute):
"""DataFrame Wrapper around SoftImpute"""
def __init__(self, shrinkage_value=None, convergence_threshold=0.001,
max_iters=100,max_rank=None,n_power_iterations=1,init_fill_method="zero",
min_value=None,max_value=None,normalizer=None,verbose=True):
super(SoftImputeDf, self).__init__(shrinkage_value=shrinkage_value,
convergence_threshold=convergence_threshold,
max_iters=max_iters,max_rank=max_rank,
n_power_iterations=n_power_iterations,
init_fill_method=init_fill_method,
min_value=min_value,max_value=max_value,
normalizer=normalizer,verbose=False)
def fit_transform(self, X, y=None):
assert isinstance(X, pd.DataFrame), "Must be pandas dframe"
for col in X.columns:
if X[col].isnull().sum() < 10:
X[col].fillna(0.0, inplace=True)
z = super(SoftImputeDf, self).fit_transform(X.values)
df = pd.DataFrame(z, index=X.index, columns=X.columns)
cats = list(X.select_dtypes(include='category'))
df[cats] = df[cats].astype('category')
# return pd.DataFrame(z, index=X.index, columns=X.columns)
return df