有没有办法从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数组。显然这是一个非常简单的例子,但更大的数组元素方式复制非常烦人。
答案 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
更改为您想要的任何内容。