来自另一个numpy数组中对象属性的新numpy数组

时间:2016-06-08 23:01:34

标签: python numpy

有没有办法从numpy数组中提取元素属性?例如,说我有:

import numpy as np

class foo():
    def __init__(self, value):
        self.bar = value

obj_array = np.empty((2, 2), dtype='object')
for i in range(obj_array.shape[0]):
    for j in range(obj_array.shape[1]):
        obj_array[i, j] = foo(i+j)

bar_array_hard_way = np.empty_like(obj_array)
for i in range(obj_array.shape[0]):
    for j in range(obj_array.shape[1]):
        bar_array_hard_way[i, j] = obj_array[i, j].bar

在这里,我有一个对象数组。每个对象都有一些属性。我希望有一种灵活的内置方式将这些属性提取为一个新的numpy数组。显然这是一个非常简单的例子,但更大的数组元素方式复制非常烦人。

2 个答案:

答案 0 :(得分:1)

我认为最快的方法是将Python的operator.attrgetter与numpy的np.frompyfunction结合起来 - 第一种方法是提供快速的本地代码内联方式来检索对象&# 39; s属性。第二,将普通的Python函数转换为Numpy的广播函数,该函数可以在一次调用中处理整个数组 -

所以,你的电话是:

from operator import attrgetter
import numpy as np
# code to build obj_array
...
bar_array_easy_way = np.frompyfunc(attrgetter("bar"), 1, 1)(obj_array)

快速比较使用fromtiterator在一半的时间内从我的对象构建一个100万个int数组 - 此外,fromiterator无法使用dtype=object构建数组 - 只需修复大小元素。

请注意attrgetter本身就是一个"功能工厂" - 它接受一个属性名称,并返回一个将接受任何对象并返回该属性的函数。返回的函数依次传递给frompyfunc - 它接受其他2个参数以允许numpy使其广播魔术:输入参数的数量和我们函数的返回结果的数量。

答案 1 :(得分:0)

您可以将新数组创建为:

bar_array = np.reshape(
    np.fromiter((x.bar for x in obj_array.flat), dtype=float),
    obj_array.shape)

dtype更改为您想要的任何内容。