NaN 值的序号编码器问题

Ordinal encoder issues with NaN values

我有一个包含空格作为缺失值的数据框,因此我使用正则表达式将它们替换为 NaN 值。我遇到的问题是当我想使用序号编码来替换分类值时。到目前为止我的代码如下:

    x=pd.DataFrame(np.array([30,"lawyer","France",
                             25,"clerk","Italy",
                             22," ","Germany",
                             40,"salesman","EEUU",
                             34,"lawyer"," ",
                             50,"salesman","France"]
                             
            ).reshape(6,3))
    x.columns=["age","job","country"]
    x = x.replace(r'^\s*$', np.nan, regex=True)

    oe=preprocessing.OrdinalEncoder()
    df.job=oe.fit_transform(df["job"].values.reshape(-1,1))

我收到以下错误:

Input contains NaN

我希望工作列被替换为数字,例如:[1,2,-1,3,1,3]。

您可以尝试使用 factorize,注意这里是从 0

开始的类别
x.job.mask(x.job==' ').factorize()[0]
Out[210]: array([ 0,  1, -1,  2,  0,  2], dtype=int32)

sklearn.preprocessing.OrdinalEncoder 不允许 NaN。如果你想使用它,你需要在获取到OrdinalEncoder之前删除NaN,将结果分配回列和fillna

from sklearn import preprocessing

oe = preprocessing.OrdinalEncoder()
x.loc[x.job.notna(), ['job']] = oe.fit_transform(x["job"].dropna().values.reshape(-1,1))
x['job'] = x.job.fillna(-1)

Out[52]:
  age  job  country
0  30  1.0   France
1  25  0.0    Italy
2  22 -1.0  Germany
3  40  2.0     EEUU
4  34  1.0      NaN
5  50  2.0   France

注意clerk是在lawyer之前的有序排列,所以它的ordinal-encoded值必须小于lawyer。所以 clerk0lawyer1

如果您想使用 None 值作为类别的第 0 个索引,这里有一个解决方案

注意:这里我有相同的类别项目列表,所以我为每一列使用了相同的列表,你可能有不同的列表

all_categories = data[["columns", "you", "want"]].values.ravel()
all_categories = [i for i in all_categories if pd.notnull(i)]
unique_categories = [None] + list(pd.unique(all_categories))

oe_cat = OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1, categories=[unique_categories for _ in ["columns", "you", "want"]])
oe_cat.fit(merged[["columns", "you", "want"]])