Pandas 中的自定义虚拟编码
Custom Dummy Coding in Pandas
我有一个包含事件数据的数据框。我有两列:小学和中学。 Primary 和 Secondary 列均包含标签列表(例如,['Fun event'、'Dance party'])。
primary secondary combined
['booze', 'party'] ['singing', 'dance'] ['booze', 'party', 'singing', 'dance']
['concert'] ['booze', 'vocals'] ['concert', 'booze', 'vocals']
我想对数据进行虚拟编码,以便主列的代码为 1,非观察列的代码为 0,辅助列中的值的值为 .5。像这样:
combined booze party singing dance concert vocals
['booze', 'party', 'singing', 'dance'] 1 1 .5 .5 0 0
['concert', 'booze', 'vocals'] .5 0 0 0 1 .5
这是一种通过将 primary
和 secondary
列的值转换为数据框上的列的方法:
df = pd.DataFrame({
'primary': [['booze', 'party'], ['concert']],
'secondary': [['singing', 'dance'], ['booze', 'vocals']],
})
# create primary and secondary indicator columns
iprim = df.primary.apply(lambda v: pd.Series([1] * len(v), index=v))
isec = df.secondary.apply(lambda v: pd.Series([.5] * len(v), index=v))
# join with primary, then update from secondary columns
df = df.join(iprim).join(isec, rsuffix='_')
df.drop([c for c in df.columns if c.endswith('_')], axis=1, inplace=True)
df.update(isec)
df.fillna(0)
=>
primary secondary booze concert party dance singing vocals
0 [booze, party] [singing, dance] 1.0 0.0 1.0 0.5 0.5 0.0
1 [concert] [booze, vocals] 0.5 1.0 0.0 0.0 0.0 0.5
注意第二个 .join()
使用 rsuffix 添加已经在 primary
中的列,而 .update()
用于覆盖主列中的值。 .drop()
删除这些列。重新排列以首选小学而不是中学。
df1=pd.get_dummies(df.combined.apply(pd.Series).stack()).sum(level=0)
df1[df1.apply(lambda x : [x.name in y for y in df.iloc[x.index,2]])]-=0.5
df1
Out[173]:
booze concert dance party singing vocals
0 1.0 0 0.5 1 0.5 0.0
1 0.5 1 0.0 0 0.0 0.5
数据输入:
df = pd.DataFrame({'primary': [['booze', 'party'] , ['concert']],
'secondary': [['singing', 'dance'], ['booze', 'vocals']],
'combined': [['booze', 'party', 'singing', 'dance'], ['concert', 'booze', 'vocals']]})
我有一个包含事件数据的数据框。我有两列:小学和中学。 Primary 和 Secondary 列均包含标签列表(例如,['Fun event'、'Dance party'])。
primary secondary combined
['booze', 'party'] ['singing', 'dance'] ['booze', 'party', 'singing', 'dance']
['concert'] ['booze', 'vocals'] ['concert', 'booze', 'vocals']
我想对数据进行虚拟编码,以便主列的代码为 1,非观察列的代码为 0,辅助列中的值的值为 .5。像这样:
combined booze party singing dance concert vocals
['booze', 'party', 'singing', 'dance'] 1 1 .5 .5 0 0
['concert', 'booze', 'vocals'] .5 0 0 0 1 .5
这是一种通过将 primary
和 secondary
列的值转换为数据框上的列的方法:
df = pd.DataFrame({
'primary': [['booze', 'party'], ['concert']],
'secondary': [['singing', 'dance'], ['booze', 'vocals']],
})
# create primary and secondary indicator columns
iprim = df.primary.apply(lambda v: pd.Series([1] * len(v), index=v))
isec = df.secondary.apply(lambda v: pd.Series([.5] * len(v), index=v))
# join with primary, then update from secondary columns
df = df.join(iprim).join(isec, rsuffix='_')
df.drop([c for c in df.columns if c.endswith('_')], axis=1, inplace=True)
df.update(isec)
df.fillna(0)
=>
primary secondary booze concert party dance singing vocals
0 [booze, party] [singing, dance] 1.0 0.0 1.0 0.5 0.5 0.0
1 [concert] [booze, vocals] 0.5 1.0 0.0 0.0 0.0 0.5
注意第二个 .join()
使用 rsuffix 添加已经在 primary
中的列,而 .update()
用于覆盖主列中的值。 .drop()
删除这些列。重新排列以首选小学而不是中学。
df1=pd.get_dummies(df.combined.apply(pd.Series).stack()).sum(level=0)
df1[df1.apply(lambda x : [x.name in y for y in df.iloc[x.index,2]])]-=0.5
df1
Out[173]:
booze concert dance party singing vocals
0 1.0 0 0.5 1 0.5 0.0
1 0.5 1 0.0 0 0.0 0.5
数据输入:
df = pd.DataFrame({'primary': [['booze', 'party'] , ['concert']],
'secondary': [['singing', 'dance'], ['booze', 'vocals']],
'combined': [['booze', 'party', 'singing', 'dance'], ['concert', 'booze', 'vocals']]})