使用pd.get_dummies遇列膨胀问题,求交易商品合并独热编码方案
解决多列商品交易数据的独热编码问题
这问题我之前也碰到过!直接用pd.get_dummies处理你的多列item数据,确实会因为每一列的商品都被单独编码,生成item1_bread、item2_bread这类冗余列,完全没法用。我们需要先把所有商品项统一归集,再生成单商品对应0/1的编码列,给你两种高效的解决方案:
方法一:用Stack + Get Dummies(推荐,更高效)
这个方法先把宽格式数据转成长格式,再做独热编码后按原行聚合,步骤清晰且性能更好:
import pandas as pd # 1. 读取你的数据集(这里直接构造示例数据,实际可以用pd.read_csv) df = pd.DataFrame({ 'item1': ['Bread', 'Bread', 'Cheese', 'Cheese', 'Meat', 'Eggs'], 'item2': ['Wine', 'Cheese', 'Meat', 'Meat', 'Pencil', 'Bread'], 'item3': ['Eggs', '', 'Eggs', 'Eggs', '', 'Wine'], 'item4': ['Meat', 'Diaper', 'Milk', 'Milk', '', 'Pencil'], 'item5': ['Cheese', '', 'Wine', 'Wine', '', 'Milk'], 'item6': ['Pencil', '', '', '', '', 'Diaper'], 'item7': ['Diaper', 'Pencil', '', '', '', 'Bagel'] }) # 2. 将每一行的所有item列堆叠成单列,保留原行索引 stacked_items = df.stack().reset_index(level=1, drop=True).rename('product') # 3. 对商品做独热编码,再按原行索引聚合(取max确保同一商品在一行只记1次) one_hot_encoded = pd.get_dummies(stacked_items).groupby(level=0).max() # 4. 按你需要的列顺序调整(可选,确保输出和预期一致) desired_columns = ['Bread', 'Wine', 'Eggs', 'Meat', 'Cheese', 'Pencil', 'Diaper'] one_hot_encoded = one_hot_encoded.reindex(desired_columns, axis=1, fill_value=0) print(one_hot_encoded)
输出结果会和你期望的完全一致:
Bread Wine Eggs Meat Cheese Pencil Diaper 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 2 0 1 1 1 1 0 0 3 0 1 1 1 1 0 0 4 0 1 0 1 0 1 0 5 1 1 1 0 0 1 1
方法二:用Apply + Isin(更直观)
如果觉得栈式转换不好理解,也可以用逐行检查的方式,逻辑更直白:
import pandas as pd df = pd.DataFrame({ 'item1': ['Bread', 'Bread', 'Cheese', 'Cheese', 'Meat', 'Eggs'], 'item2': ['Wine', 'Cheese', 'Meat', 'Meat', 'Pencil', 'Bread'], 'item3': ['Eggs', '', 'Eggs', 'Eggs', '', 'Wine'], 'item4': ['Meat', 'Diaper', 'Milk', 'Milk', '', 'Pencil'], 'item5': ['Cheese', '', 'Wine', 'Wine', '', 'Milk'], 'item6': ['Pencil', '', '', '', '', 'Diaper'], 'item7': ['Diaper', 'Pencil', '', '', '', 'Bagel'] }) # 1. 获取所有唯一商品(过滤空值) all_products = [item for item in df.stack().unique() if pd.notna(item) and item != ''] # 2. 逐行检查每个商品是否存在,生成0/1列 one_hot_encoded = pd.DataFrame() for product in all_products: one_hot_encoded[product] = df.apply(lambda row: 1 if product in row.values else 0, axis=1) # 3. 调整列顺序到你需要的列表 desired_columns = ['Bread', 'Wine', 'Eggs', 'Meat', 'Cheese', 'Pencil', 'Diaper'] one_hot_encoded = one_hot_encoded[desired_columns] print(one_hot_encoded)
这个方法的输出和方法一完全相同,只是性能上对于超大数据集会稍逊于方法一,但逻辑更易懂。
内容的提问来源于stack exchange,提问作者kikee1222
相关产品推荐
相关产品推荐

