Pandas中基于列表生成独热编码虚拟列的问题(含重复用户名困扰)
处理pandas列表列生成二进制虚拟列的方案
方法一:使用explode + crosstab
- 先构造示例数据:
import pandas as pd df = pd.DataFrame({ 'username': ['user1', 'user2', 'user3'], 'Category': [["stackoverflow", "cross_validated"], [], ["stackoverflow"]] })
- 处理空列表:将空列表替换为包含
None的列表,避免explode后丢失该行数据
df['Category'] = df['Category'].apply(lambda x: x if len(x) > 0 else [None])
- 拆分列表列并生成交叉表
# 拆分列表 exploded_df = df.explode('Category') # 生成交叉表,统计每个用户在分类下的出现次数 result = pd.crosstab(exploded_df['username'], exploded_df['Category']).reset_index() # 删除None对应的列 result = result.drop(columns=[None]) # 将空列表用户的所有分类值设为NaN result.loc[result.iloc[:, 1:].sum(axis=1) == 0, result.columns[1:]] = pd.NA
最终结果:
username stackoverflow cross_validated 0 user1 1 1 1 user2 <NA> <NA> 2 user3 1 0
方法二:使用explode + get_dummies
同样先处理空列表,再通过get_dummies生成虚拟列,最后按用户名分组取最大值:
df['Category'] = df['Category'].apply(lambda x: x if x else [None]) exploded = df.explode('Category') # 生成分类的虚拟列 dummies = pd.get_dummies(exploded['Category'], prefix='', prefix_sep='') # 合并用户名和虚拟列,按用户名分组取最大值(确保每个用户只保留一行) result = exploded[['username']].join(dummies).groupby('username').max().reset_index() # 将空列表用户的分类值设为NaN result.loc[result.iloc[:,1:].sum(axis=1)==0, result.columns[1:]] = pd.NA
内容的提问来源于stack exchange,提问作者Kevin Li
相关产品推荐
相关产品推荐

