Pandas使用NaN值填充列中的单元格,从行中的其他单元格派生值

时间:2016-06-29 01:29:11

标签: pandas dataframe scikit-learn python-3.5 sklearn-pandas

我有一个数据框:

     a    b      c
0    1    2      3 
1    1    1      1
2    3    7      NaN
3    2    3      5
...

我想使用机器学习算法填充值为NaN的“三”列(更新值)。

我不知道怎么做到位。示例代码:

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
df=pd.DataFrame([range(3), [1, 5, np.NaN], [2, 2, np.NaN], [4,5,9], [2,5,7]],columns=['a','b','c'])
x=[]
y=[]
for row in df.iterrows():
    index,data = row
    if(not pd.isnull(data['c'])):
        x.append(data[['a','b']].tolist())
        y.append(data['c'])

model = LinearRegression()
model.fit(x,y)

#this line does not do it in place.
df[~df.c.notnull()].assign(c = lambda x:model.predict(x[['a','b']]))

但是这给了我一份数据帧。我离开的唯一选择是使用for循环但是,我不想这样做。我认为使用熊猫应该有更多的pythonic方式。有人可以帮忙吗?或者还有其他方法吗?

2 个答案:

答案 0 :(得分:1)

您必须执行以下操作:

df.loc[pd.isnull(df['three']), 'three'] = _result of model_

直接修改数据框df

这样您首先过滤数据框以保留要修改的切片(pd.isnull(df['three'])),然后从该切片中选择要修改的列(three)。

在等于的右侧,它希望得到一个数组/列表/系列,其行数与过滤后的数据帧相同(在您的示例中为一行)

您可能需要根据模型准确返回的内容进行调整

修改

你可能需要像这样做

pred = model.predict(df[['a', 'b']])
df['pred'] = model.predict(df[['a', 'b']])
df.loc[pd.isnull(df['c']), 'c'] = df.loc[pd.isnull(df['c']), 'pred']

请注意,问题的重要部分来自您在示例中使用scikit learn的方式。您需要在预测时将整个数据集传递给模型。

答案 1 :(得分:0)

最简单的方法是先转置,然后在方便时进行正向填充/向后填充。 df.T.ffill().bfill().T