我如何在python中创建自己的数据类型,以便覆盖算术运算符? [英] How can I create my own datatype in python so that I could overwrite arithmetic operators?
问题描述
我目前使用Python / Numpy来处理地理/ GPS数据(喜欢它!),并且我正在面临重复执行的任务来计算由坐标对 pn = [ lon,lat]
。
我有这样一个函数: dist = geodistance(p1,p2 )
它与线性代数中的欧氏距离类似(矢量相减/差异),但出现在测地线(球形)空间而不是矩形欧氏空间中。
以编程方式,欧式距离由以下公式给出:
$ b $ pre $ dist =((p2 [0] - p1 [0])** 2 +(p2 [1] - p1 [1])** 2)** 0.5
,这相当于惯用(因缺乏更好的单词)句子
dist = p1 - p1#the范数的矢量差,减法。
目前,我的距离如下所示:
$ dist $ geodistance(p1,p2)
$打印dist
>> 44.3904032407
我想这样做:
print p2 - p1#这些点现在来自一些奇特的数据类型
>> 44.3904032407
最终目标:
track = numpy.array([[ - 51.203018 -29.996149]
[-51.203018 -29.99625]
[-51.20266 -29.996229]
[-51.20229 - 29.996309]
[-51.201519 -29.99416]],dtype = fancy)#(**)或类似
的东西print numpy.diff(track)
> ;> ndarray([[0.]
[7.03531252]
[39.82663316]
[41.50958596]
[172.49825765]])
pre>
类似的事情是:如果你取两个
datetime
对象并减去它们,操作返回一个timedelta
对象。我想减去两个坐标并得到一个测地距离作为结果。
我想知道一个类是否可以工作,但是dtype(例如float32的子类型 )会从列表创建数组时帮助很大(**,这是我从XML文件中读取的东西)。
非常感谢!
$ b $你可以通过创建一个类并写一个__ add __
或<$ c $来定义你自己的类型c> __ sub __ 方法。
例如:
class P(object):
def __init __(self,lon,lat):
self.lon = lon
self.lat = lat
def __sub __(self,other):
dist =((other.lon - self.lon)** 2 +(other.lat - self.lat)** 2)** 0.5
return dist
考虑到您目前使用列表索引语法获取点的坐标,您也可以实现这些:
class P(object):
def __init __(self,lon,lat):
self.lon = lon
self.lat = lat
$ b $ def __sub __(self,other):
dist =((other [0] - self [0])** 2 +(other [1] - self [1])** 2)** 0.5
return dist
def __getitem __(self,key):
if key == 0:
return self.lon
elif key == 1:
return self.lat
否则:
raise IndexError
$ b $ def __setitem __(self,key,value):
if key == 0:
self.lon = value
elif key == 1:
self.lat = value
else:
raise IndexError
(我知道上述可能不是最优雅的方式)。
这样,您的新课程便成为了一种直接替代方案为您正在使用的列表。
Python文档tation 包含有关您需要编写以创建用户定义类型的双下划线方法的更多信息。 (您正在查找的信息大约从页面中途开始)
I am currently using Python/Numpy to deal with geographical/GPS data (loving it!), and I am facing the recurring task to calculate distances between geographical points defined by a coordinate pair
pn = [lon, lat]
.I have a function that I use like this:
dist = geodistance(p1, p2)
which is analog to euclidean distance in linear algebra (vector subtraction/difference), but occurs in geodesical (spherical) space instead of rectangular euclidean space.Programmatically, euclidean distance is given by
dist = ((p2[0] - p1[0])**2 + (p2[1] - p1[1])**2)**0.5
Mathematically, this is equivalent to the "idiomatic" (for lack of a better word) sentence
dist = p1 - p1 # the "norm" of the vector difference, subtraction.
Currently, I get my distance like this:
p1 = [-51.598354,-29.953363] p2 = [-51.598701,-29.953045] dist = geodistance(p1, p2) print dist >> 44.3904032407
I would like to do this:
print p2 - p1 # these points now are from some fancy datatype >> 44.3904032407
And the final goal:
track = numpy.array([[-51.203018 -29.996149] [-51.203018 -29.99625 ] [-51.20266 -29.996229] [-51.20229 -29.996309] [-51.201519 -29.99416 ]], dtype=fancy) # (**) or something like print numpy.diff(track) >> ndarray([[ 0. ] [ 7.03531252] [ 39.82663316] [ 41.50958596] [ 172.49825765]])
A similar thing is: if you take two
datetime
objects and subtract them, the operation returns atimedelta
object. I want to subtract two coordinates and get a geodesic distance as the result.I wonder if a class would work, but dtype (a "subtype" of float32, for example) would help a lot upon array creation from lists (** which is how I read things from xml files).
Thanks a lot!
解决方案You can define your own types by creating a class and writing a
__add__
or__sub__
method.For example:
class P(object): def __init__(self, lon, lat): self.lon = lon self.lat = lat def __sub__(self, other): dist = ((other.lon - self.lon)**2 + (other.lat - self.lat)**2)**0.5 return dist
Given that you're currently getting the coordinates of your points using the list indexing syntax, you could also implement those:
class P(object): def __init__(self, lon, lat): self.lon = lon self.lat = lat def __sub__(self, other): dist = ((other[0] - self[0])**2 + (other[1] - self[1])**2)**0.5 return dist def __getitem__(self, key): if key == 0: return self.lon elif key == 1: return self.lat else: raise IndexError def __setitem__(self, key, value): if key == 0: self.lon = value elif key == 1: self.lat = value else: raise IndexError
(I realize that the above may not be the most elegant way to do it).
That way, your new class is a drop-in replacement for the lists you're currently using.
The Python documentation contains more information about the double-underscore methods you need to write in order to create your user-defined types. (The information you're looking for starts about half-way down the page)
这篇关于我如何在python中创建自己的数据类型,以便覆盖算术运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!