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

如何用Pandas高效实现字典映射的哑特征生成(含类别特征)

我之前处理过类似的动态特征生成需求,硬写循环确实太不灵活了——尤其是字典里的类别和动物数量经常变的时候。下面给你几个高效且易维护的实现方案,从简洁到性能优化的都有:

方案1:简洁的列表推导式+Concat组合

这个方案代码量少,易读性高,适合字典结构比较简单的场景:

import pandas as pd

random_animals = pd.DataFrame(
    {'description':['xdogx','xcatx','xhamsterx','xdogx' ,'xhorsex','xdonkeyx','xcatx']}
)
cat_dict = {'category_a':['dog','cat'] ,'category_b':['horse','donkey']}

# 批量生成单个动物的特征列
animal_features = pd.concat(
    [
        random_animals['description'].str.contains(animal, regex=False).astype(int).rename(f'is_{animal}')
        for category in cat_dict.values()
        for animal in category
    ],
    axis=1
)

# 合并原数据与动物特征列
result_df = pd.concat([random_animals, animal_features], axis=1)

# 批量生成类别特征列:只要类别下有一个动物匹配,就标记为1
for cat_name, animal_list in cat_dict.items():
    result_df[f'is_{cat_name}'] = result_df[[f'is_{animal}' for animal in animal_list]].any(axis=1).astype(int)

print(result_df)

思路说明:

  • 用列表推导式遍历字典中所有动物,一次性生成所有is_{animal}列,再用pd.concat合并,避免了逐列赋值的循环;
  • 类别特征列利用any(axis=1)判断该类别下是否有动物匹配,转成int类型得到0/1结果,逻辑清晰。

方案2:基于透视表的灵活映射法

如果你的字典结构可能更复杂(比如多层嵌套、多对多映射),这个方案的扩展性更强:

import pandas as pd

random_animals = pd.DataFrame(
    {'description':['xdogx','xcatx','xhamsterx','xdogx' ,'xhorsex','xdonkeyx','xcatx']}
)
cat_dict = {'category_a':['dog','cat'] ,'category_b':['horse','donkey']}

# 把字典展开为「类别-动物」的映射DataFrame
category_mapping = pd.DataFrame(
    [(cat, animal) for cat, animals in cat_dict.items() for animal in animals],
    columns=['category', 'animal']
)

# 提取所有匹配的动物,生成标记
matched_animals = random_animals['description'].str.extractall(f"({'|'.join(category_mapping['animal'])})")[0].reset_index()
matched_animals['value'] = 1

# 透视生成单个动物的特征列
animal_pivot = matched_animals.pivot(index='level_0', columns='0', values='value').fillna(0).astype(int)
animal_pivot.columns = [f'is_{col}' for col in animal_pivot.columns]

# 合并原数据与动物特征列
result_df = random_animals.join(animal_pivot, how='left').fillna(0).astype(int)

# 基于映射表生成类别特征列
cat_feature_df = animal_pivot.T.join(category_mapping.set_index('animal')['category']).groupby('category').sum().T
cat_feature_df.columns = [f'is_{col}' for col in cat_feature_df.columns]

# 合并类别特征列
result_df = result_df.join(cat_feature_df)

print(result_df)

思路说明:

  • 先把字典转成结构化的映射表,后续所有操作都基于这个表,避免硬编码;
  • 用extractall一次性提取所有匹配的动物,再通过透视表生成特征列,适配多匹配场景;
  • 类别特征列通过分组求和生成,自动适配类别下的动物数量变化。

方案3:Numpy矩阵加速的高性能方案

如果你的数据集很大(十万级以上行),这个方案利用Numpy的矩阵操作大幅提升性能:

import pandas as pd
import numpy as np

random_animals = pd.DataFrame(
    {'description':['xdogx','xcatx','xhamsterx','xdogx' ,'xhorsex','xdonkeyx','xcatx']}
)
cat_dict = {'category_a':['dog','cat'] ,'category_b':['horse','donkey']}

# 提取所有动物的列表
all_animals = [animal for animals in cat_dict.values() for animal in animals]

# 生成匹配矩阵:每行对应一条数据,每列对应一个动物的匹配结果
match_matrix = np.array([
    random_animals['description'].str.contains(animal, regex=False)
    for animal in all_animals
]).T.astype(int)

# 转成动物特征DataFrame
animal_features = pd.DataFrame(match_matrix, columns=[f'is_{animal}' for animal in all_animals])

# 合并原数据
result_df = pd.concat([random_animals, animal_features], axis=1)

# 生成类别特征列:用sum+clip替代any,性能更优
for cat_name, animal_list in cat_dict.items():
    result_df[f'is_{cat_name}'] = result_df[[f'is_{a}' for a in animal_list]].sum(axis=1).clip(0, 1).astype(int)

print(result_df)

思路说明:

  • 用Numpy把所有匹配结果转成二维矩阵,相比多次concat,矩阵操作的内存效率和计算速度更高;
  • 用sum(axis=1).clip(0,1)替代any(axis=1),在大数据量下性能提升明显,结果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:33