Python中不常见特性级别的一种热编码
我有一个带有分类因子的模型。我使用Python中不常见特性级别的一种热编码,python,pandas,machine-learning,scikit-learn,one-hot-encoding,Python,Pandas,Machine Learning,Scikit Learn,One Hot Encoding,我有一个带有分类因子的模型。我使用pandas.get\u dummies将其编码为一个热编码 然而,分类因素有许多不常见的层次。如果我使用pandas.get_dummies重新编码新数据,新列可能会“关闭”,因为新级别不会出现在新数据中 我正在考虑做以下工作: dummies_df = pd.get_dummies(list_of_all_possible_levels) dummies_df[:] = 0 dummies_df.drop(dummies_df.index[1:], in
pandas.get\u dummies
将其编码为一个热编码
然而,分类因素有许多不常见的层次。如果我使用pandas.get_dummies重新编码新数据,新列可能会“关闭”,因为新级别不会出现在新数据中
我正在考虑做以下工作:
dummies_df = pd.get_dummies(list_of_all_possible_levels)
dummies_df[:] = 0
dummies_df.drop(dummies_df.index[1:], inplace=True)
# If there are 10 levels this becomes a 10x10 Dataframe. I only need
# one 'empty' row and drop everything after the first.
# Let's say the DataFrame looks like this:
df['categorical_factor', 'numeric_factor', 'other_numeric_factor']
# I want to do something where I flag the column of the feature as 1
# and append the one-row dummies_df to each row of df
for cat in df.categorical_factor:
dummies_df[cat] = 1
df['numeric_factor', 'other_numeric_factor'] + dummies_df
我只是不知道是应该像这样循环遍历行,还是有更好的“笛卡尔乘积”类型的答案。如果这是R,我只会执行cbind(df,dummies\u df)
,因为R知道回收dummies\u df的值
或者我应该使用熊猫。在新数据上获取虚拟对象,并将缺少的级别作为新列加入,如下所示:
new_dat['missing_level_1'] = [0 for _ in new_dat.index]
new_dat['missing_level_2'] = [0 for _ in new_dat.index]
编辑:样本数据
df
现在
+---------+---+---+---------+---------+---------+
| (index) | A | B | level_1 | level_2 | level_3 |
+---------+---+---+---------+---------+---------+
| 0 | 0 | 3 | 1 | 0 | 0 |
| 1 | 1 | 4 | 0 | 1 | 0 |
| 2 | 2 | 5 | 0 | 0 | 1 |
+---------+---+---+---------+---------+---------+
+---------+---+---+---------+---------+
| (index) | A | B | level_1 | level_2 |
+---------+---+---+---------+---------+
| 0 | 5 | 8 | 1 | 0 |
| 1 | 6 | 9 | 0 | 1 |
| 2 | 7 | 7 | 0 | 1 |
+---------+---+---+---------+---------+
而新的_df
现在
+---------+---+---+---------+---------+---------+
| (index) | A | B | level_1 | level_2 | level_3 |
+---------+---+---+---------+---------+---------+
| 0 | 0 | 3 | 1 | 0 | 0 |
| 1 | 1 | 4 | 0 | 1 | 0 |
| 2 | 2 | 5 | 0 | 0 | 1 |
+---------+---+---+---------+---------+---------+
+---------+---+---+---------+---------+
| (index) | A | B | level_1 | level_2 |
+---------+---+---+---------+---------+
| 0 | 5 | 8 | 1 | 0 |
| 1 | 6 | 9 | 0 | 1 |
| 2 | 7 | 7 | 0 | 1 |
+---------+---+---+---------+---------+
(缺少level_3
列。)
我想要新的
+---------+---+---+---------+---------+---------+
| (index) | A | B | level_1 | level_2 | level_3 |
+---------+---+---+---------+---------+---------+
| 0 | 5 | 8 | 1 | 0 | 0 |
| 1 | 6 | 9 | 0 | 1 | 0 |
| 2 | 7 | 7 | 0 | 1 | 0 |
+---------+---+---+---------+---------+---------+
最稳定的解决方案是
重新索引
假人的数据帧
对第一个(原型)数据帧进行编码时,您还记得虚拟列的列表:
# the initial encoding
levels=['level_1', 'level_2', 'level_3']
df_original = pd.DataFrame({'levels': levels, 'A': [0,1,2], 'B': [3,4,5]})
dummies = pd.get_dummies(df_original.levels)
df = df_original.drop('levels', axis=1).join(dummies)
# remember the levels and their order
dummy_columns = list(dummies.columns)
然后,强制新的虚拟数据帧具有相同的列:
# encoding another dataframe
new_levels=['level_1', 'level_2', 'level_2']
new_df_original = pd.DataFrame({'levels': new_levels, 'A': [5,6,7], 'B': [8,9,7]})
# this is where I use the remembered information
new_dummies = pd.get_dummies(new_df_original.levels). \
reindex(columns=dummy_columns).fillna(0).astype(int)
new_df = new_df_original.drop('levels', axis=1).join(new_dummies)
print(new_df)
它给出了您想要的结果:
A B level_1 level_2 level_3
0 5 8 1 0 0
1 6 9 0 1 0
2 7 7 0 1 0
你能为你的问题添加样本数据吗?你的新的_级别包含两次级别_2而不是级别_3。纠正这一点,你将在纽约获得3级_df@Vaishali关键是级别3不在
new_df
DataFrame中new_df
可以是大约5000条记录,但不包含级别level_3
。哦,你的意思是,你需要在new_df中使用一个新的列级别_3,该列级别没有级别_3?你考虑过特征散列吗?它将分类值映射到列索引,但您不需要在培训数据中看到所有可能的分类值。