Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:对使用对象数组的函数调用进行矢量化_Python_Arrays_Python 3.x_Numpy_Vectorization - Fatal编程技术网

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

Python:对使用对象数组的函数调用进行矢量化,python,arrays,python-3.x,numpy,vectorization,Python,Arrays,Python 3.x,Numpy,Vectorization,我有一个对象数组。我还有一个函数,一次需要来自两个对象的信息。我希望将对函数的调用矢量化,以便它一次计算所有调用,而不是使用循环遍历必需的一对对象 如果我用必要的数据创建一个数组,我就可以实现这一点。然而,这在一定程度上违背了使用对象的目的 这是代码。它目前使用数组方法工作,只需要在函数中注释/取消注释一行就可以切换到“object”模式,但我非常希望这样做 我得到的错误是:TypeError:只有包含一个元素的整数数组才能转换为索引 import numpy as np import time

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

如果我用必要的数据创建一个数组,我就可以实现这一点。然而,这在一定程度上违背了使用对象的目的

这是代码。它目前使用数组方法工作,只需要在函数中注释/取消注释一行就可以切换到“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)

问题是,当我向函数传递一个整数数组时,当我使用对象数组(实际上是列表)时,它不会返回一个答案数组(我想要的向量化)。如果我使用数组(没有对象,每个元素中只有数据),它就可以工作。但正如我所说的,在我看来,这违背了存储对象信息的初衷。我真的需要在数组中存储相同的信息吗?

我不能发表评论,很抱歉误用了答案部分

如果numpy数组的数据类型是python对象,则numpy数组的内存不连续。操作的矢量化可能不会大大提高性能(如果有的话)。也许您应该尝试使用numpy结构化数组

假设对象具有属性a和b,并且它们是双精度浮点数,那么

import numpy as np

numberOfObjects = 6

myStructuredArray = np.zeros(
    (numberOfObjects,),
    [("a", "f8"), ("b", "f8")],
)
可以像这样初始化对象0的各个属性

myStructuredArray["a"][0] = 1.0
myStructuredArray["a"] = [1,2,3,4,5,6]

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

myStructuredArray["a"][0] = 1.0
myStructuredArray["a"] = [1,2,3,4,5,6]

print(myStructuredArray)


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

如果numpy数组的数据类型是python对象,则numpy数组的内存不连续。操作的矢量化可能不会大大提高性能(如果有的话)。也许您应该尝试使用numpy结构化数组

假设对象具有属性a和b,并且它们是双精度浮点数,那么

import numpy as np

numberOfObjects = 6

myStructuredArray = np.zeros(
    (numberOfObjects,),
    [("a", "f8"), ("b", "f8")],
)
可以像这样初始化对象0的各个属性

myStructuredArray["a"][0] = 1.0
myStructuredArray["a"] = [1,2,3,4,5,6]

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

myStructuredArray["a"][0] = 1.0
myStructuredArray["a"] = [1,2,3,4,5,6]

print(myStructuredArray)


numpy.ufunc
当给定一个对象数据类型数组时,遍历该数组,并尝试对每个元素应用一个CooResponse方法

例如,
np.abs
尝试应用
方法。让我们向类中添加这样的方法:

In [31]: class ExampleObject():
    ...: 
    ...:     def __init__(self, r):
    ...:         self.r       = r
    ...:     def __abs__(self):
    ...:         return self.r
    ...:     
现在创建阵列:

In [32]: indexArray = 5   #arbitrary choice of array index
    ...: sizeArray = 10  
    ...: 
    ...: 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])
并从列表中创建一个对象数据类型数组:

In [33]: exampleArr = np.array(exampleList)

In [34]: exampleArr
Out[34]: 
array([<__main__.ExampleObject object at 0x7fbb541eb9b0>,
       <__main__.ExampleObject object at 0x7fbb541eba90>,
       <__main__.ExampleObject object at 0x7fbb541eb3c8>,
       <__main__.ExampleObject object at 0x7fbb541eb978>,
       <__main__.ExampleObject object at 0x7fbb541eb208>,
       <__main__.ExampleObject object at 0x7fbb541eb128>,
       <__main__.ExampleObject object at 0x7fbb541eb198>,
       <__main__.ExampleObject object at 0x7fbb541eb358>,
       <__main__.ExampleObject object at 0x7fbb541eb4e0>,
       <__main__.ExampleObject object at 0x7fbb541eb048>], 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.ufunc
当给定一个对象数据类型数组时,遍历该数组,并尝试对每个元素应用一个CooResponse方法

例如,
np.abs
尝试应用
方法。让我们向类中添加这样的方法:

In [31]: class ExampleObject():
    ...: 
    ...:     def __init__(self, r):
    ...:         self.r       = r
    ...:     def __abs__(self):
    ...:         return self.r
    ...:     
现在创建阵列:

In [32]: indexArray = 5   #arbitrary choice of array index
    ...: sizeArray = 10  
    ...: 
    ...: 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])
并从列表中创建一个对象数据类型数组:

In [33]: exampleArr = np.array(exampleList)

In [34]: exampleArr
Out[34]: 
array([<__main__.ExampleObject object at 0x7fbb541eb9b0>,
       <__main__.ExampleObject object at 0x7fbb541eba90>,
       <__main__.ExampleObject object at 0x7fbb541eb3c8>,
       <__main__.ExampleObject object at 0x7fbb541eb978>,
       <__main__.ExampleObject object at 0x7fbb541eb208>,
       <__main__.ExampleObject object at 0x7fbb541eb128>,
       <__main__.ExampleObject object at 0x7fbb541eb198>,
       <__main__.ExampleObject object at 0x7fbb541eb358>,
       <__main__.ExampleObject object at 0x7fbb541eb4e0>,
       <__main__.ExampleObject object at 0x7fbb541eb048>], 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数学只适用于数字类型。对象数据类型只包含指向内存中其他位置对象的指针。这种数组的数学运算必须迭代,就像对相同对象的列表进行迭代一样。可以使用列表为对象数据类型数组编制索引。但是您不能一次从所有这些对象中提取
r
属性。您必须使用类似于
coords
的构造来实现这一点。我还没有消化您的代码,但请记住,快速numpy数学只适用于数字类型。对象数据类型只包含指向内存中其他位置对象的指针。这种数组的数学运算必须迭代,就像对相同对象的列表进行迭代一样。可以使用列表为对象数据类型数组编制索引。但是您不能一次从所有这些对象中提取
r
属性。您必须使用类似于
coords
的构造来实现这一点。通过创建这样一个结构化数组来扩展您的注释。我已经做到了,但我想让你获得荣誉。通过创建这样一个结构化数组来扩展你的评论。我已经做到了,但我想让你得到荣誉。使用这种技术,你已经将对象列表转换为一个numpy对象数组。我有什么理由保留我的物品清单吗?出于天真无知,我列出了一张物品清单。。。如果每次我真的使用它时,我都需要将它转换为一个数组,那么我是否应该从一个numpy数组开始,并在转换每个循环时节省一些时间?在真实的程序中,这个循环超过1000万次:)这没有一个通用的答案。这取决于您打算如何构造对象数组。列表附加比数组连接更快,并且与通过预分配数组的迭代相竞争。使用此技术,您已将对象列表转换为对象的numpy数组。我有什么理由保留我的物品清单吗?出于天真无知,我列出了一张物品清单。。。如果每次我真的使用它时,我都需要将它转换为一个数组,那么我是否应该从一个numpy数组开始,并在转换每个循环时节省一些时间?在实际的程序中,这个循环超过1000万t