所以我有一个pandas数据框,其中某些列的值是list类型,并且混合了非数字和数字数据。
示例数据
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
答案 0 :(得分:1)
使用unnesting
取消嵌套列表以分隔鱼卵并呼叫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')
答案 1 :(得分:1)
我使用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
答案 2 :(得分:0)
转到:
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
当您既没有“任何”也没有“核心”时,整行为零。
祝你好运。