You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将多列视为一组进行One Hot Encoding编码?

对DataFrame分组列执行联合One-Hot编码

我明白你的需求:你希望把多列同类型的数据当成一个组来做One-Hot编码,比如Countries1和Countries2合并后取唯一值生成统一的类别列,而不是单独对每列编码。下面我给你两种实用的实现方案,用Python的pandas和sklearn都能搞定。

先看示例数据

假设你的DataFrame长这样:

import pandas as pd

df = pd.DataFrame({
    'Countries1': ['USA', 'Canada'],
    'Cities1': ['NY', 'Toronto'],
    'Countries2': ['Canada', 'Mexico'],
    'Cities2': ['Vancouver', 'Mexico City']
})

你要把列索引[0,2](对应Countries1和Countries2)作为一组,[1,3](对应Cities1和Cities2)作为另一组,生成合并后的One-Hot列。


方案1:纯Pandas实现(无需额外库)

这种方法逻辑直观,适合小数据集,不用依赖sklearn:

def group_one_hot_encode(df, column_groups, group_names=None):
    encoded_dfs = []
    # 给分组默认命名,也支持自定义
    if group_names is None:
        group_names = [f"Group{i}" for i in range(len(column_groups))]
    
    for group_name, cols in zip(group_names, column_groups):
        # 取出当前分组的所有列(兼容列索引和列名两种传入方式)
        group_cols = df.iloc[:, cols] if isinstance(cols[0], int) else df[cols]
        # 获取该分组所有唯一值(去重后排序保证一致性)
        unique_vals = sorted(pd.unique(group_cols.values.ravel()))
        
        # 为每个唯一值生成One-Hot列
        for val in unique_vals:
            # 每行只要分组内任意一列等于该值,就标记为1,否则0
            encoded_col = group_cols.apply(lambda row: 1 if val in row.values else 0, axis=1)
            encoded_col.name = f"{group_name}_{val}"
            encoded_dfs.append(encoded_col)
    
    # 合并原DataFrame和编码后的列,也可以选择删除原分组列(注释里有代码)
    result_df = pd.concat([df] + encoded_dfs, axis=1)
    # 可选:删除原分组列
    # all_group_cols = [col for group in column_groups for col in group]
    # result_df = result_df.drop(df.columns[all_group_cols], axis=1)
    
    return result_df

# 调用函数:传入列索引分组,也可以直接传列名比如[['Countries1','Countries2'], ['Cities1','Cities2']]
encoded_df = group_one_hot_encode(df, [[0,2], [1,3]], group_names=['Country', 'City'])
print(encoded_df)

输出结果

Countries1  Cities1 Countries2     Cities2  Country_Canada  Country_Mexico  Country_USA  City_Mexico City  City_NY  City_Toronto  City_Vancouver
0        USA       NY     Canada    Vancouver              1              0           1                   0          1               0                  1
1     Canada  Toronto     Mexico  Mexico City              1              1           0                   1          0               1                  0

方案2:用Sklearn的MultiLabelBinarizer(更高效)

如果你的数据集较大,用sklearn的工具会更高效,代码也更简洁:

from sklearn.preprocessing import MultiLabelBinarizer

def group_one_hot_encode_sklearn(df, column_groups, group_names=None):
    encoded_dfs = []
    if group_names is None:
        group_names = [f"Group{i}" for i in range(len(column_groups))]
    
    for group_name, cols in zip(group_names, column_groups):
        group_cols = df.iloc[:, cols] if isinstance(cols[0], int) else df[cols]
        # 把每行的多列值转换成一个列表(比如['USA', 'Canada'])
        rows_as_lists = group_cols.values.tolist()
        
        # 用MultiLabelBinarizer生成编码
        mlb = MultiLabelBinarizer()
        encoded_data = mlb.fit_transform(rows_as_lists)
        # 转换成DataFrame并命名列
        encoded_df = pd.DataFrame(encoded_data, columns=[f"{group_name}_{val}" for val in mlb.classes_])
        encoded_dfs.append(encoded_df)
    
    result_df = pd.concat([df] + encoded_dfs, axis=1)
    # 可选删除原分组列
    # all_group_cols = [col for group in column_groups for col in group]
    # result_df = result_df.drop(df.columns[all_group_cols], axis=1)
    
    return result_df

# 调用函数
encoded_df_sklearn = group_one_hot_encode_sklearn(df, [[0,2], [1,3]], group_names=['Country', 'City'])
print(encoded_df_sklearn)

这个方法和方案1的输出完全一致,但处理大数据集时速度更快,而且是sklearn的标准工具,稳定性更好。


注意事项

  1. 缺失值处理:如果你的分组列里有NaN,两种方法都会把NaN当成一个类别生成对应的编码列。如果不需要,可以先对原DataFrame做缺失值填充(比如df.fillna('Unknown', inplace=True))或者删除缺失行。
  2. 列名灵活性:你可以根据需求修改编码列的命名规则,比如去掉分组前缀,或者用更贴合业务的名称。
  3. 原列保留:函数默认保留原DataFrame的列,如果你不需要,可以取消注释里的删除代码。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:29:44