使用 pandas 的 get_dummies 数据框数据不完整
get_dummies of dataframe with incomplete data using pandas
我有这个包含分类和非分类数据的 DataFrame,我想对其进行虚拟编码,但并非我知道的所有可能的虚拟值都出现在数据中。
例如,让我们使用以下 DataFrame:
>>> df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "x"], "c": ["h", "h", "i"]})
>>> df
a b c
0 1 x h
1 2 y h
2 3 x i
列 a
具有非分类值,但列 b
和 c
都是分类值。
现在假设第 b
列可以包含类别 x
、y
和 z
,第 c
列可以包含类别 h
, i
、j
和 k
>>> dummy_map = {"b": ["x", "y", "z"], "c": ["h", "i", "j", "k"]}
我想对其进行编码,以便生成的数据帧如下所示:
>>> df_encoded
a b_x b_y b_z c_h c_i c_j c_k
0 1 1 0 0 1 0 0 0
1 2 0 1 0 1 0 0 0
2 3 1 0 0 0 1 0 0
我目前的解决方案如下:
df_encoded = pd.get_dummies(df)
for k, v in dummy_map.items():
for cat in v:
name = k + "_" + cat
if name not in result:
df_encoded[name] = 0
但在我看来有点低效和不优雅。
那么有没有更好的解决方案呢?
使用Index.union
with vae values generated by list comprehension and f-string
s and DataFrame.reindex
:
c = [f'{k}_{x}' for k, v in dummy_map.items() for x in v]
print (c)
['b_x', 'b_y', 'b_z', 'c_h', 'c_i', 'c_j', 'c_k']
df_encoded = pd.get_dummies(df)
vals = df_encoded.columns.union(c, sort=False)
df_encoded = df_encoded.reindex(vals, axis=1, fill_value=0)
print (df_encoded)
a b_x b_y c_h c_i b_z c_j c_k
0 1 1 0 1 0 0 0 0
1 2 0 1 1 0 0 0 0
2 3 1 0 0 1 0 0 0
如果值应该按 union
排序:
df_encoded = pd.get_dummies(df)
vals = df_encoded.columns.union(c)
df_encoded = df_encoded.reindex(vals, axis=1, fill_value=0)
print (df_encoded)
a b_x b_y b_z c_h c_i c_j c_k
0 1 1 0 0 1 0 0 0
1 2 0 1 0 1 0 0 0
2 3 1 0 0 0 1 0 0
我有这个包含分类和非分类数据的 DataFrame,我想对其进行虚拟编码,但并非我知道的所有可能的虚拟值都出现在数据中。
例如,让我们使用以下 DataFrame:
>>> df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "x"], "c": ["h", "h", "i"]})
>>> df
a b c
0 1 x h
1 2 y h
2 3 x i
列 a
具有非分类值,但列 b
和 c
都是分类值。
现在假设第 b
列可以包含类别 x
、y
和 z
,第 c
列可以包含类别 h
, i
、j
和 k
>>> dummy_map = {"b": ["x", "y", "z"], "c": ["h", "i", "j", "k"]}
我想对其进行编码,以便生成的数据帧如下所示:
>>> df_encoded
a b_x b_y b_z c_h c_i c_j c_k
0 1 1 0 0 1 0 0 0
1 2 0 1 0 1 0 0 0
2 3 1 0 0 0 1 0 0
我目前的解决方案如下:
df_encoded = pd.get_dummies(df)
for k, v in dummy_map.items():
for cat in v:
name = k + "_" + cat
if name not in result:
df_encoded[name] = 0
但在我看来有点低效和不优雅。 那么有没有更好的解决方案呢?
使用Index.union
with vae values generated by list comprehension and f-string
s and DataFrame.reindex
:
c = [f'{k}_{x}' for k, v in dummy_map.items() for x in v]
print (c)
['b_x', 'b_y', 'b_z', 'c_h', 'c_i', 'c_j', 'c_k']
df_encoded = pd.get_dummies(df)
vals = df_encoded.columns.union(c, sort=False)
df_encoded = df_encoded.reindex(vals, axis=1, fill_value=0)
print (df_encoded)
a b_x b_y c_h c_i b_z c_j c_k
0 1 1 0 1 0 0 0 0
1 2 0 1 1 0 0 0 0
2 3 1 0 0 1 0 0 0
如果值应该按 union
排序:
df_encoded = pd.get_dummies(df)
vals = df_encoded.columns.union(c)
df_encoded = df_encoded.reindex(vals, axis=1, fill_value=0)
print (df_encoded)
a b_x b_y b_z c_h c_i c_j c_k
0 1 1 0 0 1 0 0 0
1 2 0 1 0 1 0 0 0
2 3 1 0 0 0 1 0 0