我有一个如下数据框:
test = {"viral": "pos", "Status": "positive", "Age": 59, "score": 5}
test2 = {"viral": "neg"}
df = pd.DataFrame.from_dict([test, test2])
我想将字符列(病毒,状态)编码为序数,但不要理会数值。所需的输出是具有相同列名的numpy数组。
如果我使用sklearn的OrdinalEncoder,它将不处理NaN值。即使没有NaN值,它仍将对数字列进行序数编码。我想在字符列中用0填充NaN值,但在数字列中保留NaN。
最简单的方法是什么?
所需的输出(以numpy数组形式):
Age Status score viral
0 59.0 1 5.0 1
1 NaN 0 NaN 0
谢谢! 杰克
编辑:我还希望在使用{i: dict(enumerate(v)) for i, v in enumerate(enc.categories_)}
时从编码值映射到enc=OrdinalEncoder()
之类的原始值(请参见Vectorize 2D character array column-wise)
答案 0 :(得分:2)
更新,当有NaN时,它将代码显示为-1,如果您需要NaN,则可以使用replace
df=pd.DataFrame([test,test2])
df.dtypes
Out[152]:
Age float64
Status object
score float64
viral object
dtype: object
listc=df.columns[df.dtypes=='object']
for x in listc:
df[x]=df[x].astype('category').cat.codes
df
Out[156]:
Age Status score viral
0 59.0 0 5.0 1
1 NaN -1 NaN 0
答案 1 :(得分:1)
enc = sklearn.preprocessing.LabelEncoder()
mask = df.dtypes.eq(np.object)
df.loc[:, mask] = df.loc[:, mask].astype(str).apply(enc.fit_transform)
为了能够inverse_transform
,可以使用defaultdict
中的LabelEncoders
进行创建。 key
是您的选择。我建议使用列名:直观而简单
from collections import defaultdict
enc = defaultdict(sklearn.preprocessing.LabelEncoder)
mask = df.dtypes.eq(np.object)
df.loc[:, mask] = df.loc[:, mask].astype(str).apply(lambda s: enc[s.name].fit_transform(s))
Status viral
0 1 1
1 0 0
df.loc[:, mask].apply(lambda s: enc[s.name].inverse_transform(s))
Status viral
0 positive pos
1 NaN neg