Python:对使用对象数组的函数调用进行矢量化

2024-09-27 21:31:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组对象。我还有一个函数,一次需要两个对象的信息。我希望将对函数的调用矢量化,以便它一次计算所有调用,而不是使用循环遍历必需的一对对象。在

如果我用必要的数据创建一个数组,我就可以使用这个方法了。然而,这部分地破坏了使用对象的目的。在

这是密码。它目前使用的是array方法,只需要在函数中对一行进行注释/取消注释,就可以切换到不起作用的“object”模式,但我很希望这样做。在

我得到的错误是:TypeError:只有一个元素的整数数组才能转换为索引

import numpy as np
import time as time

class ExampleObject():

    def __init__(self, r):
        self.r       = r

def ExampleFunction(x):
    """ WHAT I REALLY WANT """
#    answer = exampleList[x].r - exampleList[indexArray].r 
    """WHAT I AM STUCK WITH """
    answer = coords[x] - exampleList[indexArray].r
    return answer

indexArray = 5   #arbitrary choice of array index
sizeArray = 1000    

exampleList = []
for i in range(sizeArray):
    r = np.random.rand()
    exampleList.append( ExampleObject( r ) )

index_list = np.arange(0,sizeArray,1)
index_list = np.delete(index_list,indexArray)

coords = np.array([h.r for h in exampleList])

answerArray = ExampleFunction(index_list)

问题是,当我把一个整数数组传递给函数时,当我使用对象数组(实际上是列表)时,它没有返回答案数组(我想要的向量化)。如果我使用一个数组(没有对象,每个元素中只有数据)就可以了。但正如我所说的,这在我的头脑中是失败的,从一开始就把信息储存在物体上。我真的需要在数组中存储相同的信息吗?在


Tags: 数据对象方法函数answer信息元素index
2条回答

numpy.ufunc当给定一个object dtype数组时,遍历该数组,并尝试对每个元素应用一个协同响应方法。在

例如,np.abs尝试应用__abs__方法。让我们将这样一个方法添加到类中:

In [31]: class ExampleObject():
    ...: 
    ...:     def __init__(self, r):
    ...:         self.r       = r
    ...:     def __abs__(self):
    ...:         return self.r
    ...:     

现在创建阵列:

^{pr2}$

并从列表中生成一个object dtype数组:

^{3}$

现在我们可以通过调用np.abs函数来获得r值的数组:

In [35]: np.abs(exampleArr)
Out[35]: 
array([0.28411876298913485, 0.5807617042932764, 0.30566195995294954,
       0.39564156171554554, 0.28951905026871105, 0.5500945908978057,
       0.40908712567465855, 0.6469497088949425, 0.7480045751535003,
       0.710425181488751], dtype=object)

它还可以处理数组的索引元素:

In [36]: np.abs(exampleArr[:3])
Out[36]: 
array([0.28411876298913485, 0.5807617042932764, 0.30566195995294954],
      dtype=object)

这很方便,但我不能保证速度。在其他测试中,我发现对象数据类型上的迭代比数值数组元素上的迭代(在Python中)快,但比列表迭代慢。在

In [37]: timeit np.abs(exampleArr)
3.61 µs ± 131 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [38]: timeit [h.r for h in exampleList]
985 ns ± 31.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [39]: timeit np.array([h.r for h in exampleList])
3.55 µs ± 88.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

我不能评论,抱歉误用了答案部分。。。在

如果numpy数组的数据类型是python对象,则numpy数组的内存不是连续的。如果有的话,操作的矢量化可能不会提高性能太多。也许你应该试试numpy结构化数组。在

假设对象有属性a&b,它们是双精度浮点数,然后。。。在

import numpy as np

numberOfObjects = 6

myStructuredArray = np.zeros(
    (numberOfObjects,),
    [("a", "f8"), ("b", "f8")],
)

可以像这样初始化对象0的各个属性

^{pr2}$

或者您可以像这样初始化所有对象的单个属性

^{3}$
[(1., 0.) (2., 0.) (3., 0.) (4., 0.) (5., 0.) (6., 0.)]

相关问题 更多 >

    热门问题