对多列类型的 pandas 数据帧执行一次性编码
Perform one-hot encoding on pandas dataframe on multiple column types
所以我有一个 pandas 数据框,其中某些列具有列表类型的值以及非数字和数字数据列的混合。
示例数据
dst_address dst_enforcement fwd_count ...
1 1.2.3.4 [Any,core] 8
2 3.4.5.6 [] 9
3 6.7.8.9 [Any] 10
4 8.10.3.2 [core] 0
到目前为止,我已经能够通过这两行代码找出哪些列是非数字的
col_groups = df.columns.to_series().groupby(df.dtypes).groups
non_numeric_cols = col_groups[np.dtype('O')]
在所有这些非数字列中,我需要弄清楚哪些列的数据类型是列表,我想对所有非数字列(包括那些列表类型)执行一次性编码
编辑:我对上述示例的预期输出类似于
1.2.3.4 | 3.4.5.6 | 6.7.8.9 | 8.10.3.2 | empty | Any | core | fwd_count ...
1 1 0 0 0 0 1 1 8
2 0 1 0 0 1 0 0 9
3 0 0 1 0 0 1 0 10
4 0 0 0 1 0 0 1 0
使用 to unnest the lists to seperate roes and call pd.get_dummies()
:
df_new=unnesting(df,['dst_enforcement']).combine_first(df)
df_new.dst_enforcement=df_new.dst_enforcement.apply(lambda y: 'empty' if len(y)==0 else y)
m=pd.get_dummies(df_new,prefix='',prefix_sep='').groupby('fwd_count').first().reset_index()
print(m)
fwd_count 1.2.3.4 3.4.5.6 6.7.8.9 8.10.3.2 Any core empty
0 0.0 0 0 0 1 0 1 0
1 8.0 1 0 0 0 1 0 0
2 9.0 0 1 0 0 0 0 1
3 10.0 0 0 1 0 1 0 0
为了方便添加函数:
def unnesting(df, explode):
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx
return df1.join(df.drop(explode, 1), how='left')
试一试:
non_numeric_cols = col_groups[np.dtype('O')]
for non in non_numeric_cols:
print(pd.get_dummies(df[non].apply(pd.Series)))
输出:
0_1.2.3.4 0_3.4.5.6 0_6.7.8.9 0_8.10.3.2
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 0 1
0_Any 0_core 1_core
0 1 0 1
1 0 0 0
2 1 0 0
3 0 1 0
当您既没有 "Any" 也没有 "core" 时,整行都是零。
祝你好运。
我使用3个步骤如下:
df['dst_enforcement'] = df.dst_enforcement.apply(lambda x: x if x else ['empty'])
dm1 = pd.get_dummies(df[df.columns.difference(['dst_enforcement'])], prefix='', prefix_sep='')
dm2 = df.dst_enforcement.str.join('-').str.get_dummies('-')
pd.concat([dm1, dm2], axis=1)
Out[1221]:
fwd_count 1.2.3.4 3.4.5.6 6.7.8.9 8.10.3.2 Any core empty
1 8 1 0 0 0 1 1 0
2 9 0 1 0 0 0 0 1
3 10 0 0 1 0 1 0 0
4 0 0 0 0 1 0 1 0
所以我有一个 pandas 数据框,其中某些列具有列表类型的值以及非数字和数字数据列的混合。
示例数据
dst_address dst_enforcement fwd_count ...
1 1.2.3.4 [Any,core] 8
2 3.4.5.6 [] 9
3 6.7.8.9 [Any] 10
4 8.10.3.2 [core] 0
到目前为止,我已经能够通过这两行代码找出哪些列是非数字的
col_groups = df.columns.to_series().groupby(df.dtypes).groups
non_numeric_cols = col_groups[np.dtype('O')]
在所有这些非数字列中,我需要弄清楚哪些列的数据类型是列表,我想对所有非数字列(包括那些列表类型)执行一次性编码
编辑:我对上述示例的预期输出类似于
1.2.3.4 | 3.4.5.6 | 6.7.8.9 | 8.10.3.2 | empty | Any | core | fwd_count ...
1 1 0 0 0 0 1 1 8
2 0 1 0 0 1 0 0 9
3 0 0 1 0 0 1 0 10
4 0 0 0 1 0 0 1 0
使用pd.get_dummies()
:
df_new=unnesting(df,['dst_enforcement']).combine_first(df)
df_new.dst_enforcement=df_new.dst_enforcement.apply(lambda y: 'empty' if len(y)==0 else y)
m=pd.get_dummies(df_new,prefix='',prefix_sep='').groupby('fwd_count').first().reset_index()
print(m)
fwd_count 1.2.3.4 3.4.5.6 6.7.8.9 8.10.3.2 Any core empty
0 0.0 0 0 0 1 0 1 0
1 8.0 1 0 0 0 1 0 0
2 9.0 0 1 0 0 0 0 1
3 10.0 0 0 1 0 1 0 0
为了方便添加函数:
def unnesting(df, explode):
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx
return df1.join(df.drop(explode, 1), how='left')
试一试:
non_numeric_cols = col_groups[np.dtype('O')]
for non in non_numeric_cols:
print(pd.get_dummies(df[non].apply(pd.Series)))
输出:
0_1.2.3.4 0_3.4.5.6 0_6.7.8.9 0_8.10.3.2
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 0 1
0_Any 0_core 1_core
0 1 0 1
1 0 0 0
2 1 0 0
3 0 1 0
当您既没有 "Any" 也没有 "core" 时,整行都是零。
祝你好运。
我使用3个步骤如下:
df['dst_enforcement'] = df.dst_enforcement.apply(lambda x: x if x else ['empty'])
dm1 = pd.get_dummies(df[df.columns.difference(['dst_enforcement'])], prefix='', prefix_sep='')
dm2 = df.dst_enforcement.str.join('-').str.get_dummies('-')
pd.concat([dm1, dm2], axis=1)
Out[1221]:
fwd_count 1.2.3.4 3.4.5.6 6.7.8.9 8.10.3.2 Any core empty
1 8 1 0 0 0 1 1 0
2 9 0 1 0 0 0 0 1
3 10 0 0 1 0 1 0 0
4 0 0 0 0 1 0 1 0