4

首先,我想知道在数值工作中使用 OO 方法是否是一般的好习惯。

其次,OO 的一个可能用例是将某个模型的参数封装在某个对象中。比如说,我想研究形式为 ax^2 + bx +c 的抛物线。所以我会将 a、b、c 封装在某个抛物线对象中。我可以绘制它等等。现在,假设我想探索抛物线垂直轴的位置。基本上,如果没有 OO,我可以为几个给定的 c 值绘制所有垂直轴位置 wrt a 和 b(这将是两个 numpy 数组)的表面。

我的问题是,如何在不牺牲(太多)numpy 性能的情况下使用额外的 OO 层进行这样的表面绘图?

额外说明

使用 OO 方法的一种方法是为一系列参数 a 和 b 的值创建抛物线对象矩阵。但是这种方式将处理可能非常大的对象,而不是参数范围的普通 numpy 数组。

4

2 回答 2

4

我建议不要使用对象数组,因为您最终会失去使用 numpy 的几乎所有性能优势。我们的结构或编码更像这样:

class Points:

    def __init__(self, x, y):
        self.x = np.asarray(x)
        self.y = np.asarray(y)

    def shift_left(self, distance):
        self.x -= distance

x = np.zeros(10000)
y = np.zeros(10000)

points_obj = Points(x, y)

现在您可以创建函数、方法等,这些函数、方法等在points_obj知道这一点的情况下进行操作,points_obj.x并且point_obj.y是 numpy 数组(可能大小为 1,或者可能更大)。如果您需要能够索引到 points_obj,您总是可以__getitem__在您的类上定义一个方法。

于 2012-09-20T19:33:50.833 回答
2

无论是否面向对象,您都可以使用相同的数值算法。我不太明白你的问题。OO更多的是关于程序结构和数据之间的连接。方法中的数字可以与普通程序程序中的数字相同。 - 编辑 -

当你向量化它的方法时,你可以很快地制作你的抛物线数组。您当然可以对更复杂的向量进行矢量化。

import numpy as np

class parabola:
    a = 0.0
    b = 0.0
    c = 0.0
    def __init__(self,a,b,c):
        self.a = a
        self.b = b
        self.c = c
    def set_a(self, new_a):
        self.a = new_a
    def set_b(self, new_b):
        self.b = new_b
    def set_c(self, new_c):
        self.c = new_c
    def get_a(self):
        return self.a
    def get_b(self):
        return self.b
    def get_c(self):
        return self.c

vpara = np.vectorize(parabola)
vgeta = np.vectorize(parabola.get_a)
vgetb = np.vectorize(parabola.get_b)
vgetc = np.vectorize(parabola.get_c)


a = np.zeros(10000)
b = np.zeros(10000)
c = np.zeros(10000)
a[:]  = [i for i in xrange(10000)]
b[:]  = [2*i for i in xrange(10000)]
c[:]  = [i*i for i in xrange(10000)]

objs = np.empty((10000), dtype=object)
objs[:] = vpara(a,b,c)

print vgeta(objs[1:10:2]),vgetc(objs[9900:9820:-3])
于 2012-09-19T20:54:52.233 回答