将Pandas虚拟变量列合并为单列(逆向pd.get_dummies)
问题描述
我手头有这么一个Pandas DataFrame:
id Apple Apricot Banana Clementine Orange Pear Pineapple 0 01 1 1 0 0 0 0 0 1 02 0 0 1 1 1 1 0 2 03 0 0 0 0 1 0 1
想把它转换成下面这种更简洁的格式,该怎么操作呢?
id fruits 0 01 Apple, Apricot 1 02 Banana, Clementine, Orange, Pear 2 03 Orange, Pineapple
解决方案
这事儿其实挺简单的,用Pandas的几个方法组合就能搞定,给你两种思路:
方法一:逐行处理(适合小数据集)
这种方法直观易懂,适合数据量不大的情况:
import pandas as pd # 先构造原始DataFrame(如果已经有了就跳过这步) df = pd.DataFrame({ 'id': ['01', '02', '03'], 'Apple': [1, 0, 0], 'Apricot': [1, 0, 0], 'Banana': [0, 1, 0], 'Clementine': [0, 1, 0], 'Orange': [0, 1, 1], 'Pear': [0, 1, 0], 'Pineapple': [0, 0, 1] }) # 核心步骤:遍历每一行,筛选出值为1的水果列,用逗号连接 df['fruits'] = df.apply( lambda row: ', '.join(row[row == 1].index.drop('id')), axis=1 # axis=1表示按行处理 ) # 只保留需要的id和fruits列 result_df = df[['id', 'fruits']] print(result_df)
简单解释下:
apply(lambda row: ..., axis=1)会逐行处理每一条数据row[row == 1].index能拿到当前行里值为1的所有列名(也就是对应的水果)- 用
drop('id')把非水果的id列排除掉 - 最后用
', '.join()把这些水果名称拼成字符串
方法二:向量化操作(适合大数据集)
如果你的数据集很大,逐行处理效率会比较低,试试这种向量化的方法,速度更快:
import pandas as pd # 同样先构造原始DataFrame df = pd.DataFrame({ 'id': ['01', '02', '03'], 'Apple': [1, 0, 0], 'Apricot': [1, 0, 0], 'Banana': [0, 1, 0], 'Clementine': [0, 1, 0], 'Orange': [0, 1, 1], 'Pear': [0, 1, 0], 'Pineapple': [0, 0, 1] }) # 把id设为索引,方便后续分组 df_indexed = df.set_index('id') # 筛选出值为1的单元格,转成行格式,再按id分组聚合 result_df = df_indexed[df_indexed == 1].stack().reset_index() result_df = result_df.groupby('id')['level_1'].agg(', '.join).reset_index(name='fruits') print(result_df)
这个方法的逻辑:
df_indexed[df_indexed == 1].stack()会把所有值为1的单元格“堆叠”成多行,其中level_1列就是水果名称- 然后按
id分组,用agg(', '.join)把每个id对应的水果名称拼接起来 - 最后重置索引,得到目标格式的DataFrame
内容的提问来源于stack exchange,提问作者ah bon
相关产品推荐
相关产品推荐

