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

Python中如何高效实现数据到矩阵的映射,加速指定循环代码段

待优化代码段
# the part I want to speed up
for x, y_dict in zip(x_data, y_data):
    x_index = x_to_index[x]
    for y_key, y_data in y_dict.items():
        y_slice = slice(*y_to_index[y_key])
        total_matrix[ y_slice, x_index ] += y_data
        latest_value[ y_slice, x_index ]  = y_data
        n_matrix[ y_slice, x_index ]     += 1
优化方案

以下两种方案均可实现性能大幅提升,可根据你的场景选择:

  • 方案1:Numba JIT编译优化(最推荐,提速100倍以上)
    仅需极小的代码改动,通过Numba的即时编译能力将Python循环直接编译为机器码,消除Python解释器开销,是数值类循环优化的首选方案。
    首先安装依赖:pip install numba
    优化后代码:

    import numpy as np
    from numba import njit
    
    # 预处理映射与数据为数组格式,适配Numba编译要求
    x_index_arr = np.array([x_to_index[x] for x in x_data])
    max_y_key = max(y_to_index.keys())
    y_index_arr = np.zeros((max_y_key + 1, 2), dtype=np.int32)
    for k, (start, end) in y_to_index.items():
        y_index_arr[k] = [start, end]
    y_val_arr = np.zeros((len(y_data), max_y_key + 1), dtype=np.int32)
    for i, y_dict in enumerate(y_data):
        for k, v in y_dict.items():
            y_val_arr[i, k] = v
    
    @njit
    def run_update(x_index_arr, y_index_arr, y_val_arr, total_matrix, latest_value, n_matrix):
        x_count = len(x_index_arr)
        y_key_count = y_val_arr.shape[1]
        for x_idx in range(x_count):
            col = x_index_arr[x_idx]
            for y_k in range(y_key_count):
                val = y_val_arr[x_idx, y_k]
                y_start, y_end = y_index_arr[y_k]
                total_matrix[y_start:y_end, col] += val
                latest_value[y_start:y_end, col] = val
                n_matrix[y_start:y_end, col] += 1
        return total_matrix, latest_value, n_matrix
    
    # 执行更新,首次调用会有编译开销,后续调用无额外开销
    total_matrix, latest_value, n_matrix = run_update(x_index_arr, y_index_arr, y_val_arr, total_matrix, latest_value, n_matrix)
    
  • 方案2:纯NumPy向量化实现(无额外依赖,提速10~50倍)
    不需要安装第三方依赖,仅通过NumPy的原生向量化操作替代Python循环,适合不能引入新依赖的场景。
    优化后代码:

    import numpy as np
    
    # 预处理所有映射
    x_indices = np.array([x_to_index[x] for x in x_data])
    y_ranges = np.array([y_to_index[k] for k in range(100)])
    
    all_rows = []
    all_cols = []
    all_vals = []
    for col, y_dict in zip(x_indices, y_data):
        for y_k, val in y_dict.items():
            y_s, y_e = y_ranges[y_k]
            rows = np.arange(y_s, y_e, dtype=np.int32)
            all_rows.append(rows)
            all_cols.append(np.full_like(rows, col))
            all_vals.append(np.full_like(rows, val))
    
    all_rows = np.concatenate(all_rows)
    all_cols = np.concatenate(all_cols)
    all_vals = np.concatenate(all_vals)
    
    # 批量执行累加操作
    np.add.at(total_matrix, (all_rows, all_cols), all_vals)
    np.add.at(n_matrix, (all_rows, all_cols), 1)
    
    # 处理latest_value,取每个位置最后一次的赋值
    _, last_idx = np.unique(np.stack([all_rows, all_cols], axis=1)[::-1], axis=0, return_index=True)
    last_idx = len(all_rows) - 1 - last_idx
    latest_value[all_rows[last_idx], all_cols[last_idx]] = all_vals[last_idx]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 22:09:02