【发布时间】:2013-11-04 23:50:31
【问题描述】:
在你反对之前:每个程序员都是懒惰的。否则你不会手动编程和做所有事情!
一个简单的例子。
我有一个类Line,它包含处理一条线所需的一切(例如使用两个顶点/点创建的对象)。这个类实际上非常复杂,为了简单、可维护和清晰起见,我想保持这样:我用两个顶点提供一个类,并输出一些困难的结果,例如两点之间的距离。
问题
现在,问题在于,虽然我需要跟踪这些单独的行,但有时我还希望将它们作为一个整体来处理。例如,我想计算由多条线组成的路径的长度。
目前的解决方案和不足
我创建了一个名为 Lines 的类,它还为此提供了一些方法。
Lines 目前是numpy.ndarray 的孩子,这不是很好:
- 命名空间被 ndarray 的方法弄乱了;
- 我正在使用
ufuncs 在Lines中围绕Line的方法提供一个包装器,但是在这样的两个地方维护代码很繁琐。
问题
那么,你们将如何有效地“矢量化”Line 类,同时跟踪各个行?
我可以将所有内容都放在Lines 中,并将Line 视为一个特例,我试过了,但这确实会影响清晰度,并且使各个行的所有引用都很难实现和维护。
代码示例
import numpy as np
class Line:
def __init__ (self, input_points):
assert len(np.array(input_points).squeeze()) == 2
self._points = np.array(input_points)
def get_distance(self):
return np.sqrt(((self._points[0]-self._points[1])**2).sum())
from itertools import combinations
class Lines(np.ndarray):
_get_dists = np.frompyfunc(Line.get_distance, 1, 1)
def __new__(cls, data):
comb = [Line(el) for el in combinations(data, 2)]
obj = np.asarray(comb).view(cls)
obj = obj.squeeze()
return obj
def get_all_distances(self):
return self._get_dists(self)
【问题讨论】:
-
Lines只是Lines 的一般集合,还是它们以某种方式相互关联?另外,你能举一个你想“矢量化”的方法的具体例子吗? -
目前,所有数据都被加载并在
Lines中拆分,以创建一组Line对象。这些对象是Lines暂时保留的唯一数据。我目前正在研究一种将 all 数据作为 numpy 数组保存在内存中的方法。Lines将直接访问该数组,而对该数组子部分的引用将传递给Line实例。 -
拥有一些代码(不是你的整个程序,只是一个小的、可运行的示例),而不必猜测……
-
这个距离如何?
(self._points[0] + self._points[1])/2 -
@Gael:嗯,你已经成功了一半。 ;)
标签: python numpy vectorization