用fancyimpute和pandas进行数据估算

时间:2017-07-21 13:42:24

标签: python python-3.x pandas imputation fancyimpute

我有一个大熊猫数据成名 <iframe width="900" height="506" src="https://www.youtube.com/v/NWCep6fo2y0" frameborder="0" allowfullscreen></iframe> 。它有很多缺失。丢弃行/或逐行不是一种选择。输入中位数,平均值或最常用的值也不是一种选择(因此,df和/或pandas的估算很难做到这一点。

我遇到了一个名为scikit的简洁包(你可以找到它here)。但是我有一些问题。

以下是我的工作:

fancyimpute

但是,#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 arraydf_numeric转换为数组。

as_matrix()

输出是一个缺少列标签的数据框。有没有办法检索标签?

4 个答案:

答案 0 :(得分:6)

在代码后添加以下行:

df_filled.columns = df_numeric.columns
df_filled.index = df_numeric.index

答案 1 :(得分:4)

我看到了对幻想的归咎和熊猫的无奈。这是使用递归覆盖方法的相当基本的包装器。接收并输出一个数据框-完整的列名。这种包装器可以很好地与管道配合使用。

DELIMITER //
CREATE TRIGGER before_insert_income
    BEFORE INSERT ON income_30
    FOR EACH ROW
BEGIN
    IF NEW.income = (select income from income_30 where ID=NEW.ID and date=(select max(date) from income_30)) THEN
        UPDATE income_30 set date = NEW.date where ID=NEW.ID;
END IF;
END; //
DELIMITER ;

答案 2 :(得分:2)

<div id="vir">
    <p>Viridis colors</p>
</div>

由fancyimpute对象的df=pd.DataFrame(data=mice.complete(d), columns=d.columns, index=d.index) 方法返回的np.array(无论是鼠标还是KNN)作为pandas数据帧的内容.complete()提供,其中cols和索引是与原始数据框相同。

答案 3 :(得分:1)

我非常感谢@ 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