以不同于 One-Hot 的方式编码 Dataframe
Encoding a Dataframe differently than One-Hot
假设我有一个类似的 df,用于记录计算机游戏中 6 个玩家 (3v3) 中每个玩家的可玩角色选择。
data = {'Pick_1_team1': ['A','A','A','B','C'],
'Pick_2_team1': ['D','D','E','F','F'],
'Pick_3_team1': ['G','G','A','M','O'],
'Pick_1_team2': ['Q','Q','S','S','A'],
'Pick_2_team2': ['V','W','X','A','B'],
'Pick_3_team2': ['R','X','W','W','R']}
df = pd.DataFrame(data)
df_enc = pd.get_dummies(df)
当我使用 panda 的 get_dummies 时,我将得到一个具有以下结构的稀疏 df(例如,不是示例 df 的实际编码)
对于两支球队,每个选择位都有所有可能的选择 (A-Z)。
| P1_T1_A | P1_T1_B | P1_T1_C | ... | P2_T1_A | ... | P3_T1_Z | ... | P1_T2_A | P1_T2_B | ... | P3_T2_Z |
|---------|---------|---------|-----|---------|-----|---------|-----|---------|---------|-----|---------|
| 0 | 0 | 1 | ... | 0 | ... | 0 | ... | 1 | 0 | ... | 1 |
| 1 | 0 | 0 | ... | 0 | ... | 0 | ... | 0 | 1 | ... | 1 |
| 1 | 0 | 0 | ... | 0 | ... | 0 | ... | 0 | 0 | ... | 0 |
这没问题,但如果您考虑更大的输入 space(有 150 多个可能的选择),table 会变得非常大。为了使其更易于管理,我正在考虑以某种方式将其编码为以下格式:
每个类别(角色)一列 x 每个团队 2,如果该角色被选中则为 1,否则为 0。
| T1_A | T1_B | T1_C | ... | T1_Z | ... | T2_A | T2_B | ... | T2_Z |
|------|------|------|-----|------|-----|------|------|-----|------|
| 0 | 0 | 1 | ... | 0 | ... | 1 | 1 | ... | 1 |
| 1 | 1 | 1 | ... | 0 | ... | 0 | 0 | ... | 1 |
| 1 | 0 | 0 | ... | 0 | ... | 0 | 0 | ... | 0 |
这会将特征数限制为选秀权数 x 球队数(26 个字母 * 2 个球队),而不是可能的选秀权 x 选秀权数 x 球队数(26 个字母 * 3 个选秀权 * 2 个球队)
panda 可以通过任何 built_in 函数做到这一点吗?如果不是,最简单的方法是什么?
感谢任何帮助!
谢谢
您可以通过首先选择一个具有 filter
、stack
数据的团队并使用 str.get_dummies
,然后 groupby
level=0(原始中的行df) 和 sum
。 add_prefix
到 concat
之前的列,对于两个团队,如:
df_ = pd.concat([
(df.filter(like=f'Pick_{i}').stack()
.str.get_dummies()
.groupby(level=0).sum()
.add_prefix(f'T{i}_')
) for i in [1,2] ],
axis=1)
print (df_)
T1_A T1_B T1_C T1_D T1_E T1_F T1_G T1_M T1_O T2_A T2_B T2_Q \
0 1 0 0 1 0 0 1 0 0 0 0 1
1 1 0 0 1 0 0 1 0 0 0 0 1
2 2 0 0 0 1 0 0 0 0 0 0 0
3 0 1 0 0 0 1 0 1 0 1 0 0
4 0 0 1 0 0 1 0 0 1 1 1 0
T2_R T2_S T2_V T2_W T2_X
0 1 0 1 0 0
1 0 0 0 1 1
2 0 1 0 1 1
3 0 1 0 1 0
4 1 0 0 0 0
如果只需要 1,0
个值,则将 get_dummies
与聚合 max
一起使用,如果需要计数值,则使用 sum
:
df_enc = (pd.get_dummies(df.rename(columns=lambda x:x.split('_', 2)[-1].replace('team','T')))
.max(axis=1, level=0)
.sort_index(axis=1, level=0))
print (df_enc)
T1_A T1_B T1_C T1_D T1_E T1_F T1_G T1_M T1_O T2_A T2_B T2_Q \
0 1 0 0 1 0 0 1 0 0 0 0 1
1 1 0 0 1 0 0 1 0 0 0 0 1
2 1 0 0 0 1 0 0 0 0 0 0 0
3 0 1 0 0 0 1 0 1 0 1 0 0
4 0 0 1 0 0 1 0 0 1 1 1 0
T2_R T2_S T2_V T2_W T2_X
0 1 0 1 0 0
1 0 0 0 1 1
2 0 1 0 1 1
3 0 1 0 1 0
4 1 0 0 0 0
假设我有一个类似的 df,用于记录计算机游戏中 6 个玩家 (3v3) 中每个玩家的可玩角色选择。
data = {'Pick_1_team1': ['A','A','A','B','C'],
'Pick_2_team1': ['D','D','E','F','F'],
'Pick_3_team1': ['G','G','A','M','O'],
'Pick_1_team2': ['Q','Q','S','S','A'],
'Pick_2_team2': ['V','W','X','A','B'],
'Pick_3_team2': ['R','X','W','W','R']}
df = pd.DataFrame(data)
df_enc = pd.get_dummies(df)
当我使用 panda 的 get_dummies 时,我将得到一个具有以下结构的稀疏 df(例如,不是示例 df 的实际编码)
对于两支球队,每个选择位都有所有可能的选择 (A-Z)。
| P1_T1_A | P1_T1_B | P1_T1_C | ... | P2_T1_A | ... | P3_T1_Z | ... | P1_T2_A | P1_T2_B | ... | P3_T2_Z |
|---------|---------|---------|-----|---------|-----|---------|-----|---------|---------|-----|---------|
| 0 | 0 | 1 | ... | 0 | ... | 0 | ... | 1 | 0 | ... | 1 |
| 1 | 0 | 0 | ... | 0 | ... | 0 | ... | 0 | 1 | ... | 1 |
| 1 | 0 | 0 | ... | 0 | ... | 0 | ... | 0 | 0 | ... | 0 |
这没问题,但如果您考虑更大的输入 space(有 150 多个可能的选择),table 会变得非常大。为了使其更易于管理,我正在考虑以某种方式将其编码为以下格式:
每个类别(角色)一列 x 每个团队 2,如果该角色被选中则为 1,否则为 0。
| T1_A | T1_B | T1_C | ... | T1_Z | ... | T2_A | T2_B | ... | T2_Z |
|------|------|------|-----|------|-----|------|------|-----|------|
| 0 | 0 | 1 | ... | 0 | ... | 1 | 1 | ... | 1 |
| 1 | 1 | 1 | ... | 0 | ... | 0 | 0 | ... | 1 |
| 1 | 0 | 0 | ... | 0 | ... | 0 | 0 | ... | 0 |
这会将特征数限制为选秀权数 x 球队数(26 个字母 * 2 个球队),而不是可能的选秀权 x 选秀权数 x 球队数(26 个字母 * 3 个选秀权 * 2 个球队) panda 可以通过任何 built_in 函数做到这一点吗?如果不是,最简单的方法是什么?
感谢任何帮助! 谢谢
您可以通过首先选择一个具有 filter
、stack
数据的团队并使用 str.get_dummies
,然后 groupby
level=0(原始中的行df) 和 sum
。 add_prefix
到 concat
之前的列,对于两个团队,如:
df_ = pd.concat([
(df.filter(like=f'Pick_{i}').stack()
.str.get_dummies()
.groupby(level=0).sum()
.add_prefix(f'T{i}_')
) for i in [1,2] ],
axis=1)
print (df_)
T1_A T1_B T1_C T1_D T1_E T1_F T1_G T1_M T1_O T2_A T2_B T2_Q \
0 1 0 0 1 0 0 1 0 0 0 0 1
1 1 0 0 1 0 0 1 0 0 0 0 1
2 2 0 0 0 1 0 0 0 0 0 0 0
3 0 1 0 0 0 1 0 1 0 1 0 0
4 0 0 1 0 0 1 0 0 1 1 1 0
T2_R T2_S T2_V T2_W T2_X
0 1 0 1 0 0
1 0 0 0 1 1
2 0 1 0 1 1
3 0 1 0 1 0
4 1 0 0 0 0
如果只需要 1,0
个值,则将 get_dummies
与聚合 max
一起使用,如果需要计数值,则使用 sum
:
df_enc = (pd.get_dummies(df.rename(columns=lambda x:x.split('_', 2)[-1].replace('team','T')))
.max(axis=1, level=0)
.sort_index(axis=1, level=0))
print (df_enc)
T1_A T1_B T1_C T1_D T1_E T1_F T1_G T1_M T1_O T2_A T2_B T2_Q \
0 1 0 0 1 0 0 1 0 0 0 0 1
1 1 0 0 1 0 0 1 0 0 0 0 1
2 1 0 0 0 1 0 0 0 0 0 0 0
3 0 1 0 0 0 1 0 1 0 1 0 0
4 0 0 1 0 0 1 0 0 1 1 1 0
T2_R T2_S T2_V T2_W T2_X
0 1 0 1 0 0
1 0 0 0 1 1
2 0 1 0 1 1
3 0 1 0 1 0
4 1 0 0 0 0