从NumPy中的对象数组中获取属性

时间:2012-03-20 17:25:24

标签: python numpy

假设我有一个名为Star的类,其属性为color。我可以使用star.color获得颜色。

但是如果我有这些Star个对象的NumPy数组怎么办?获取颜色数组的首选方法是什么?

我可以用

做到
colors = np.array([s.color for s in stars])

但这是最好的方法吗? 如果我可以像其他语言一样colors = star.colorcolors = star->color等,那就太棒了。在那儿 在numpy中这样做的简单方法?

3 个答案:

答案 0 :(得分:7)

最接近您想要的是使用recarray而不是ndarray Python对象:

num_stars = 10
dtype = numpy.dtype([('x', float), ('y', float), ('colour', float)])
a = numpy.recarray(num_stars, dtype=dtype)
a.colour = numpy.arange(num_stars)
print a.colour

打印

[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]

使用NumPy Python对象数组通常效率低于使用普通list,而recarray以更有效的格式存储数据。

答案 1 :(得分:3)

您可以使用numpy.fromiter(s.color for s in stars)(注意缺少方括号)。这样可以避免创建中间列表,如果你使用的是numpy,我想你可能会关心它。

(感谢@SvenMarnach和@DSM在下面的更正)。

答案 2 :(得分:0)

如果 star 是更复杂的 class,这里是获取和设置的方法 顶部带有辅助 class 的属性。

import numpy as np

class star:
    def __init__(self, mass=1, radius=1):
        self.mass = mass
        self.radius = radius

class Stars(list):

    __getattr__ = lambda self, attr: np.array([getattr(s, attr) for s in self])

    def __setattr__(self, attr, vals):
        if hasattr(vals, '__len__'):
            [s.__setattr__(attr, val) for (s,val) in zip(self,vals)]
        else:
            [s.__setattr__(attr, vals) for s in self]


s1 = star(1, 1.1)
s2 = star(2, 3)

S = Stars([s1, s2])

print(S.mass)
print(S.radius)

S.density = S.mass / S.radius**3
print(S.density)
print(s1.density)

当然,如果类可以重新实现为recarray,效率应该更高。然而,这种重新实现可能是不可取的。

注意,外部计算,如密度计算,仍然是矢量化的。通常这些可能是瓶颈,而不是设置和获取属性。