通过从 pandas 和 scikit-learn 中的非缺失值估计方程来估算缺失值

Impute missing value by estimating the equation from non missing value in pandas and scikit-learn

我有一个数据框如下图

Price        Category      Area
20           Red           100
30           Red           150
10           Red           50
25           Red           NaN
30           Red           NaN
10           Green         30
20           Green         60
30           Green         90
10           Green         30
40           Green         NaN
50           Green         NaN

根据以上,我想分别估计每个类别红色和绿色的面积和价格之间的关系。

例如这里的红色:

Area = 5 * Price

同样适用于绿色:

Area = 3 * Price

我想将其实现到 pandas 和 scikit-learn:

步数 1. 估计每个类别的面积和价格之间的关系。 2. 根据关系估算缺失值。

我在 python 和编码方面很新。

Expected output
Price        Category      Area
20           Red           100
30           Red           150
10           Red           50
25           Red           125
30           Red           150
10           Green         30
20           Green         60
30           Green         90
10           Green         30
40           Green         120
50           Green         150

您可以使用:

  1. 通过 Area / Price
  2. 获取因数
  3. GroupByCategory
  4. ffillbfill
  5. 填充 NaN
  6. Price 与新因子相乘以创建新的 Area
df['factors'] = df['Area'] / df['Price']
df['factors'] = df.groupby('Category', sort=False)['factors'].ffill().bfill()

df = df.assign(Area=df['Price'] * df['factors']).drop(columns='factors')
    Price Category  Area
0      20      Red 100.0
1      30      Red 150.0
2      10      Red  50.0
3      25      Red 125.0
4      30      Red 150.0
5      10    Green  30.0
6      20    Green  60.0
7      30    Green  90.0
8      10    Green  30.0
9      40    Green 120.0
10     50    Green 150.0

你也可以像下面这样使用字典,然后堆叠和填充:

d={'Area_Red' : 5 * df['Price'] , 'Area_Green' : 3 * df['Price']}
df_ref=pd.DataFrame(d).rename(columns=lambda x: x.split('_')[1]).stack()
df['Area']=df.set_index('Category',append=True)['Area'].fillna(df_ref).droplevel(1)

如果您只想根据 df_ref 获取值并更新 Area col(不仅仅是 fillna),请将最后一行更改为以下内容,使用 df.lookup:

d={'Area_Red' : 5 * df['Price'] , 'Area_Green' : 3 * df['Price']}
df_ref=pd.DataFrame(d).rename(columns=lambda x: x.split('_')[1]) #without stack
df['Area']=df_ref.lookup(df['Category'].index,df['Category']) 

print(df)

    Price Category  Area
0      20      Red   100
1      30      Red   150
2      10      Red    50
3      25      Red   125
4      30      Red   150
5      10    Green    30
6      20    Green    60
7      30    Green    90
8      10    Green    30
9      40    Green   120
10     50    Green   150