如何使用Pandas透视DataFrame并将新列按分组存在情况设为True/False
没问题,你想要的效果是把GROUP列的不同取值转为新列,并用布尔值标记每个ID+REV组合是否包含对应分组,这确实可以通过透视类操作实现,下面给你几个实用的方案:
方法1:用pivot_table快速实现
pivot_table是Pandas里做透视的核心工具,我们可以指定行索引为ID和REV,列为GROUP,然后用聚合函数标记“是否存在该分组”,最后填充缺失值为False:
import pandas as pd df = pd.DataFrame({'ID' : [0, 0, 1, 1, 1], 'REV' : [0, 0, 1, 1, 1], 'GROUP' : [1, 2, 1, 2, 3]}) # 生成透视表,存在则标记True,缺失填充False result = df.pivot_table( index=['ID', 'REV'], columns='GROUP', aggfunc=lambda x: True, fill_value=False ).reset_index() # 调整列名(透视表默认会生成多级列,这里展平) result.columns = ['ID', 'REV', 1, 2, 3] print(result)
运行后就能得到你想要的结果,原理很简单:只要某分组在当前ID+REV组合里出现过,聚合函数就返回True,没出现的位置用fill_value补成False。
方法2:用pd.crosstab更简洁
如果只是做这种“存在与否”的交叉标记,pd.crosstab会更省心——它天生就是用来生成交叉统计表的,我们只需要把统计结果转成布尔值就行:
import pandas as pd df = pd.DataFrame({'ID' : [0, 0, 1, 1, 1], 'REV' : [0, 0, 1, 1, 1], 'GROUP' : [1, 2, 1, 2, 3]}) # 生成交叉表,把计数转为布尔值(>0就是True) result = pd.crosstab([df['ID'], df['REV']], df['GROUP']).astype(bool).reset_index() # 调整列名 result.columns = ['ID', 'REV', 1, 2, 3] print(result)
这个方法代码更短,逻辑也直观:crosstab先统计每个组合的出现次数,astype(bool)自动把非零值转成True,零值转成False。
方法3:用get_dummies+groupby的组合
如果你更习惯用独热编码的思路,也可以先把GROUP列转成独热编码格式,再按ID和REV分组取最大值(只要组里有一个True,结果就是True):
import pandas as pd df = pd.DataFrame({'ID' : [0, 0, 1, 1, 1], 'REV' : [0, 0, 1, 1, 1], 'GROUP' : [1, 2, 1, 2, 3]}) # 对GROUP做独热编码,直接生成布尔值列 dummies = pd.get_dummies(df['GROUP'], dtype=bool) # 合并原ID/REV列,按ID+REV分组取最大值 result = pd.concat([df[['ID', 'REV']], dummies], axis=1).groupby(['ID', 'REV']).max().reset_index() print(result)
这个方法的好处是扩展性强,如果之后需要对分组做其他处理,能很方便地调整。
以上三种方法都能实现你想要的效果,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者mike_gundy123
相关产品推荐
相关产品推荐

