如何将DataFrame的列表型列值透视转换为二进制标识列?
将包含列表列的DataFrame转换为布尔值透视表的解决方案
我来帮你一步步拆解这个需求,刚好能帮你理解透视相关的操作逻辑~先明确你的核心目标:把带列表的c2列,拆分成以列表元素为列名的布尔值列(存在为True,不存在为False),同时保留c1列的对应关系。
原始数据与目标效果
先回顾你的输入和期望输出:
# 原始DataFrame import pandas as pd df = pd.DataFrame({ 'c1': ['x','y','z'], 'c2': [[1,2,3],[1,3],[2,4]] })
原始结构:
c1 c2 0 x [1, 2, 3] 1 y [1, 3] 2 z [2, 4]
期望的目标结构(数值1/0对应布尔值True/False):
c1 1 2 3 4 0 x True True True False 1 y True False True False 2 z False True False True
方法一:用explode() + pd.crosstab()(适合理解透视逻辑)
这个方法完全贴合透视的核心思路,先拆解数据再统计关联:
- 展开列表:把
c2列的每个列表元素拆成单独的行,让每一行只保留c1和单个c2元素的对应关系 - 交叉透视统计:用
pd.crosstab()统计每个c1值对应每个c2元素的出现次数 - 转换为布尔值:频次为1代表元素存在(转
True),0代表不存在(转False)
代码实现:
# 1. 展开c2列的列表,让每个元素单独占一行 df_exploded = df.explode('c2') # 2. 生成交叉表,统计每个c1对应c2元素的出现次数 cross_table = pd.crosstab(df_exploded['c1'], df_exploded['c2']) # 3. 转换为布尔值,并把c1从索引变回普通列 result = cross_table.astype(bool).reset_index().rename_axis(None, axis=1) print(result)
方法二:用str.get_dummies()(更简洁的写法)
如果想简化步骤,可以利用字符串拆分的技巧直接生成目标列:
- 把列表转为分隔符连接的字符串:比如
[1,2,3]转成"1|2|3" - 拆分字符串生成虚拟列:用
str.get_dummies()按分隔符拆分,自动生成以元素为列名的0/1列 - 合并原始列并转布尔值:和
c1列合并后,把0/1数值转为布尔值
代码实现:
# 1. 将列表转为用|分隔的字符串,再拆分生成0/1虚拟列 dummies = df['c2'].apply(lambda x: '|'.join(map(str, x))).str.get_dummies(sep='|') # 2. 和c1列合并,并转换为布尔值 result = pd.concat([df['c1'], dummies.astype(bool)], axis=1) print(result)
这两种方法都能达到你的需求,第一种更适合学习透视操作的逻辑(拆解→统计→转换),第二种则是利用pandas的字符串方法简化步骤,你可以根据自己的理解习惯选择~
内容的提问来源于stack exchange,提问作者Neckless Cage
相关产品推荐
相关产品推荐

