Numpy对象数组应用求和函数的性能优化及多方案对比问询
适配不同场景的优化方案
1. 数据源结构调整(优先级最高)
只要你存储的所有子列表长度统一,直接放弃numpy对象数组结构,转为普通二维numpy数值数组:
# 结构转换仅需一次,后续所有运算都能享受numpy向量化性能 res = np.array(list_obj_array.tolist(), dtype=np.int32) %timeit np.sum(res, axis=1)
这个方案的性能是所有方案的天花板,比任何Python层循环实现快至少一个量级,是首选方案。
2. 必须保留numpy对象数组的场景
2.1 小数据量、短子列表场景
直接使用已验证的最优方案:原生列表推导式调用内置sum
[sum(l) for l in list_obj_array]
Python内置sum是纯C实现,没有np.vectorize的额外调度开销,也没有Numba的类型适配成本,是这个场景下的最优解。
2.2 大数据量、长子列表场景
先做一次结构转换再调用numpy向量化求和,当子列表长度≥10、数组行数≥100时,转换开销会被numpy向量化运算的收益覆盖,性能反超列表推导式:
np.sum(np.array(list_obj_array.tolist()), axis=1)
3. 复杂运算场景的Numba适配方案
如果你的实际逻辑不止求和、还有更复杂的逐行运算,可以调整Numba写法适配nopython模式,规避类型错误:
import numpy as np import numba as nb from numba.typed import List @nb.njit def nb_sum_opt(typed_list): n = len(typed_list) res = np.empty(n, dtype=np.int64) for i in range(n): row_sum = 0 for num in typed_list[i]: row_sum += num res[i] = row_sum return res # 调用前仅需做一次类型转换,多次调用时分摊转换成本 typed_input = List(list_obj_array.tolist())
这个方案在数据量足够大时,性能会超过原生列表推导式,适合逻辑复杂、需要多次调用的场景。
内容的提问来源于stack exchange,提问作者sami
相关产品推荐
相关产品推荐

