from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
points = [Point(x=1.0, y=1.0), Point(x=2.0, y=2.0)]
我想计算points
列表的平均点,即结果接收Point(1.5, 1.5)
:
point = average(points) # x = 1.5, y = 1.5
例如。我知道如果np.average(points, axis=0)
是points.shape
,那就是(N, 2)
,但我宁愿保留一个命名的元组。
计算平均坐标:
import numpy as np
Point(np.average([p.x for p in points]),
np.average([p.y for p in points]))
#Point(x=1.5, y=1.5)
或者,更好地,隐式地将点列表转换为numpy数组,获得平均值,并将结果转换回Point
Point(*np.average(points, axis=0))
#Point(x=1.5, y=1.5)
也许我错过了什么,但如果你想避免numpy
那么你可以做
>>> Point(sum(p.x for p in points)/len(points),sum(p.y for p in points)/len(points))
Point(x=1.5, y=1.5)
虽然看起来有点迂回。
这是namedtuple
的一个新子类,它有一个classmethod
来从一系列点的平均值或总和构造一个新点。
from collections import namedtuple
class Point(namedtuple('Point', ['x', 'y'])):
@classmethod
def from_average(cls, points):
from_sum = cls.from_sum(points)
return cls(from_sum.x / len(points), from_sum.y / len(points))
@classmethod
def from_sum(cls, points):
if not all(isinstance(p, cls) for p in points):
raise ValueError('All items in sequence must be of type {}'.format(cls.__name__))
x = sum(p.x for p in points)
y = sum(p.y for p in points)
return cls(x, y)
point_1 = Point(1.0, 1.0)
point_2 = Point(2.0, 2.0)
point_3 = Point.from_average([point_1, point_2])
point_3
# Point(x=1.5, y=1.5)
point_4 = Point.from_sum([point_1, point_2])
point_4
# Point(x=3.0, y=3.0)
这是一种简洁的方式,只使用Python内置插件:
In [1]: from collections import namedtuple
...: Point = namedtuple('Point', ['x', 'y'])
...: points = [Point(x=1.0, y=1.0), Point(x=2.0, y=2.0)]
...:
In [2]: import statistics
In [3]: Point(*map(statistics.mean, zip(*points)))
Out[3]: Point(x=1.5, y=1.5)
你为什么一开始使用numpy
?这里没有多大意义。