如何从数据数组高效创建自定义对象的numpy数组?
创建A类实例数组的优化方法及Numpy官方推荐方案
一、简化循环的写法
如果一定要生成每个元素都是A类实例的数组,可以用列表推导替代嵌套循环,代码更简洁:
a_instances = numpy.array([[A(x, y) for y in b_vals] for x in a_vals], dtype=object)
也可以结合meshgrid的结果,先扁平化再重塑形状:
flat_a = ma.flatten() flat_b = mb.flatten() a_instances = numpy.array([A(x, y) for x, y in zip(flat_a, flat_b)], dtype=object).reshape(ma.shape)
这类方法本质还是循环,仅在语法上更简洁,性能和嵌套循环差异不大。
二、用numpy.vectorize做语法包装
numpy.vectorize可以将接收单个参数的函数转换为能处理数组的函数,用来生成实例数组:
vec_create_A = numpy.vectorize(lambda x, y: A(x, y)) a_instances = vec_create_A(ma, mb)
注意:vectorize只是语法糖,底层依然是循环,不会带来性能提升,但代码更简洁。
三、Numpy官方推荐的方案
Numpy不推荐创建元素为Python对象的数组(即dtype=object),这类数组无法利用Numpy的向量化优化,性能远低于原生数值数组。官方更建议两种替代方案:
1. 单个A实例存储数组(即你提到的第一种方式)
这种方式完全契合Numpy的向量化设计,所有操作都能利用Numpy的高效计算:
ma, mb = numpy.meshgrid(a_vals, b_vals, indexing="ij") a_instance = A(ma, mb)
后续对a.a和a.b的操作都是原生数组运算,性能最优。
2. 使用结构化数组模拟类封装
如果需要类似“每个位置有一组属性”的结构,推荐用Numpy的结构化数组,它是Numpy原生支持的类型,能兼顾结构封装和向量化性能:
# 定义和A类属性对应的结构化dtype a_dtype = numpy.dtype([('a', numpy.float64), ('b', numpy.float64)]) # 创建结构化数组 a_structured = numpy.empty(ma.shape, dtype=a_dtype) # 赋值 a_structured['a'] = ma a_structured['b'] = mb
访问时和类实例类似:a_structured[i,j]['a']、a_structured[i,j]['b'],同时所有数组操作都能高效执行。
内容的提问来源于stack exchange,提问作者HerpDerpington
相关产品推荐
相关产品推荐

