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

如何基于上下限将值映射至DataFrame新列(Pythonic实现)

高效实现DataFrame基于类型和阶段的映射赋值

问题背景

给定包含type和phase两列的DataFrame,需根据不同type对应的phase区间/精确值映射规则,为新列分配对应值。示例数据与映射规则如下:

示例数据

import pandas as pd
d = {'type': ['a','b','c','a','b','c','a','b','c',], 'phase': [-10,3,2,1,-7,-3,-1,-5,4]}
df_ = pd.DataFrame(data=d)

映射规则(含区间与精确值)

a_phase = {
    ('<', -9):0.001,
    -9:0.010,
    -8:0.022,
    -7:0.026,
    -6:0.092,
    -5:0.091,
    -4:0.082,
    -3:0.121,
    -2:0.060,
    -1:0.105,
    0:0.018,
    1:0.092,
    2:0.092,
    3:0.092,
    4:0.092,
    ('>',4):0.000,
}

b_phase = {
    ('<', -9):0.016,
    -9:0.011,
    -8:0.021,
    -7:0.028,
    -6:0.052,
    -5:0.075,
    -4:0.057,
    -3:0.102,
    -2:0.238,
    -1:0.270,
    0:0.034,
    1:0.014,
    2:0.061,
    ('>',2):0.000,
}

c_phase = {
    ('<', -9):0.016,
    -9:0.016,
    -8:0.011,
    -7:0.010,
    -6:0.038,
    -5:0.015,
    -4:0.099,
    -3:0.117,
    -2:0.216,
    -1:0.213,
    0:0.008,
    1:0.008,
    2:0.008,
    ('>',2):0.000,
}

原方案使用大量np.where语句效率极低,需更优实现方式。

最优实现方案

1. 标准化映射规则格式

将原始的混合(区间+精确值)映射规则转换为pd.cut可识别的区间格式:

def format_mapping(mapping):
    bins = []
    labels = []
    
    # 处理左开区间(< x)
    left_key = next(k for k in mapping if isinstance(k, tuple) and k[0] == '<')
    left_val = mapping.pop(left_key)
    bins.extend([-float('inf'), left_key[1]])
    labels.append(left_val)
    
    # 处理精确值(转为闭区间[x, x])
    exact_keys = sorted([k for k in mapping if isinstance(k, int)])
    for k in exact_keys:
        bins.extend([k, k])
        labels.append(mapping[k])
    
    # 处理右开区间(> x)
    right_key = next(k for k in mapping if isinstance(k, tuple) and k[0] == '>')
    right_val = mapping.pop(right_key)
    bins.extend([right_key[1], float('inf')])
    labels.append(right_val)
    
    # 去重相邻重复的bin,避免pd.cut报错
    bins = list(dict.fromkeys(bins))
    return bins, labels

# 格式化所有类型的映射规则
type_mappings = {
    'a': format_mapping(a_phase.copy()),
    'b': format_mapping(b_phase.copy()),
    'c': format_mapping(c_phase.copy())
}

2. 分组批量映射赋值

通过groupby按type分组,对每组应用pd.cut完成值匹配:

def apply_phase_mapping(group):
    type_label = group['type'].iloc[0]
    bins, labels = type_mappings[type_label]
    # 用pd.cut匹配区间,返回对应结果
    group['result'] = pd.cut(
        group['phase'], 
        bins=bins, 
        labels=labels, 
        include_lowest=True,
        right=False  # 匹配左闭右开区间,对应规则中的"< x"逻辑
    )
    return group

# 执行映射并生成结果
df_result = df_.groupby('type', group_keys=False).apply(apply_phase_mapping)

3. 结果验证

输出最终结果:

print(df_result)

输出示例:

type  phase result
0    a    -10  0.001
1    b      3     0.0
2    c      2  0.008
3    a      1  0.092
4    b     -7  0.028
5    c     -3  0.117
6    a     -1  0.105
7    b     -5  0.075
8    c      4     0.0

方案优势

  • 高效向量化:替代多分支np.where,利用pd.cut的向量化操作,大数据量下性能提升明显
  • 可扩展性强:新增类型只需添加对应映射字典,无需修改核心逻辑
  • 逻辑清晰:分组处理对应不同类型规则,区间匹配逻辑统一封装,易于维护

内容的提问来源于stack exchange,提问作者D. Price

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:06:10