给出如下数据框df1
:
df1 = pd.DataFrame({
'col1': [1,2,3,4],
'col2': [['a', 'b'], ['c'], ['a', 'd', 'b'], ['e']]
})
外观如下:
col1 col2
0 1 [a, b]
1 2 [c]
2 3 [a, d, b]
3 4 [e]
我想将col2
(每个单元格是一个列表的一列)转换成几列(a
,b
,c
,d
, e
),其中值是布尔条目,用于定义给定行中原始列表中是否存在该列名称。
输出应遵循以下格式:
df2 = pd.DataFrame({
'col1': [1,2,3,4],
'a': [True, False, True, False],
'b': [True, False, True, False],
'c': [False, True, False, False],
'd': [False, False, True, False],
'e': [False, False, False, True]
})
外观如下:
col1 a b c d e
0 1 True True False False False
1 2 False False True False False
2 3 True True False True False
3 4 False False False False True
什么是干净的方法?
答案 0 :(得分:3)
使用str.get_dummies
的替代方法可能比apply
+ pd.Series
更有效:
df1['col2'].str.join(',').str.get_dummies(sep=',').astype(bool)
a b c d e
0 True True False False False
1 False False True False False
2 True True False True False
3 False False False False True
时间:
df1.shape
(40000, 2)
%%timeit
df1['col2'].str.join(',').str.get_dummies(sep=',').astype(bool)
286 ms ± 16.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
pd.get_dummies(df1['col2'].apply(pd.Series).stack()).sum(level=0)
9.43 s ± 499 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
答案 1 :(得分:2)
一种方法
df2 = df1.reset_index().explode('col2')
new_df = pd.crosstab(df2['col1'], df2['col2']).astype(bool)
print(new_df)
col2 a b c d e
col1
1 True True False False False
2 False False True False False
3 True True False True False
4 False False False False True
或
new_df = (df1.reset_index()
.explode('col2')
.groupby(['index', 'col2'])['col1']
.any()
.unstack(fill_value=False))
new_df = (df1.reset_index()
.explode('col2')
.pivot_table(index='index',
values='col1',
columns='col2',
aggfunc='any',
fill_value=False)
)
答案 2 :(得分:0)
已解决。
pd.get_dummies(df1['col2'].apply(pd.Series).stack()).sum(level=0)