有效地计算数千个坐标对之间的距离

时间:2019-02-14 21:51:45

标签: python python-3.x list performance astropy

我有一个用python打开的目录,其中包含大约70,000行数据(ra,dec坐标和对象名称)用于各种对象。我还有另一个大约15,000个感兴趣的对象的列表,它们也出现在前面提到的目录中。对于这15,000个对象中的每一个,我想查看大型70,000个列表中是否有任何 other 对象在该对象的10弧秒内具有ra,dec坐标。如果发现这是真的,我只想标记该对象并继续进行下一个。但是,此过程要花费很长时间,因为要计算当前感兴趣的对象(总共15,000个)之间70,000个不同时间之间的距离。这将需要几天!我如何才能更有效地完成同一任务?下面是我当前的代码,其中all_objects是所有15,000个感兴趣的对象名称的列表,而catalog是前面提到的70,000个对象的表数据。

from astropy.coordinates import SkyCoord
from astropy import units as u

for obj_name in all_objects:
    obj_ind = list(catalog['NAME']).index(obj_name)
    c1 = SkyCoord(ra=catalog['RA'][obj_ind]*u.deg, dec=catalog['DEC'][obj_ind]*u.deg, frame='fk5')
    for i in range(len(catalog['NAME'])):
        if i != obj_ind:
            # Compute distance between object and other source
            c2 = SkyCoord(ra=catalog['RA'][i]*u.deg, dec=catalog['DEC'][i]*u.deg, frame='fk5')
            sep = c1.separation(c2)
            contamination_flag = False
            if sep.arcsecond <= 10:
                contamination_flag = True
                print('CONTAMINATION FOUND')
                break

1 个答案:

答案 0 :(得分:2)

1创建您自己的分隔函数

一旦您查看了实现并问自己:“我怎样才能更快地做到这一点”,这一步真的很容易

def separation(self, other):
    from . import Angle
    from .angle_utilities import angular_separation # I've put that in the code bellow so it is clearer

    if not self.is_equivalent_frame(other):
        try:
            other = other.transform_to(self, merge_attributes=False)
        except TypeError:
            raise TypeError('Can only get separation to another SkyCoord '
                            'or a coordinate frame with data')

    lon1 = self.spherical.lon
    lat1 = self.spherical.lat
    lon2 = other.spherical.lon
    lat2 = other.spherical.lat

    sdlon = np.sin(lon2 - lon1)
    cdlon = np.cos(lon2 - lon1)
    slat1 = np.sin(lat1)
    slat2 = np.sin(lat2)
    clat1 = np.cos(lat1)
    clat2 = np.cos(lat2)

    num1 = clat2 * sdlon
    num2 = clat1 * slat2 - slat1 * clat2 * cdlon
    denominator = slat1 * slat2 + clat1 * clat2 * cdlon

    return Angle(np.arctan2(np.hypot(num1, num2), denominator), unit=u.degree)

它会计算大量的余弦和正弦值,然后创建一个Angle实例并转换为度,然后转换为弧秒。

您可能不想使用Angle,也不想在开始时进行测试和转换,也不想在函数中进行导入,或者在需要性能的情况下不进行太多变量分配。

分隔功能对我来说有点沉重,应该只取数字并返回一个数字。

2使用四叉树(需要完全重写代码)

也就是说,让我们看一下算法的复杂度,它会检查每个元素是否与其他每个元素相对,复杂度为O(n**2)(大O表示法)。我们可以做得更好...

您可以使用四叉树,最坏情况下四叉树的复杂度为O(N)。如果您不熟悉Big O,则基本上意味着对15 000元素的查找将是对15 000元素而不是1的查找的225 000 000倍。次(15 000平方)...相当不错的改进... Scipy具有出色的Quad树库(我一直使用自己的库)。