将大量星系分类为一定半径的球体

Sorting large numbers of galaxies into spheres of a certain radius

我有大量的星系。我需要将这些星系分类为半径为 N 的球体,计算每个球体中的平均星系数,并根据半径 N 绘制图表。

星系作为径向坐标(赤经、赤纬和红移)存储在 .fits 文件中。我正在使用 pyFITS 和 astropy 将星系坐标转换为地球在 (0,0,0) 处的笛卡尔坐标,然后将坐标存储在具有以下结构的 numpy 数组中:((x,y,z),(x1, y1,z1), 等等)

为了将星系分成半径为 N 的球体,我从阵列中随机选择一个星系,然后遍历阵列计算随机选择的星系与当前星系之间的距离。如果距离小于或等于半径,则将其添加到球体中。重复的次数与需要计算的气泡数一样多。

我目前的方法真的很慢。我不熟悉 numpy(我一直在解决问题),而且我真的看不到比遍历所有星系更好的方法。

有没有办法更快地完成此操作(与 numpy 数组有关 - 我现在正在将它们转换为普通的 python 列表)?这就是我现在正在做的事情 (https://github.com/humz2k/EngineeringProjectBethe/blob/humza/bubbles.py)。

首先,通常最好 post 您问题所在的代码示例(例如 select 您想要保留的半径的部分),而不是链接到你的整个脚本 :)

其次,numpy数组非常适合科学编程!它们使您可以轻松地存储数据并对该数据执行矩阵运算,而无需循环遍历本机 Python 列表。如果您了解 MATLAB,它们基本上可以让您完成 MATLAB 数组所做的大部分相同的事情。可以找到更多信息 here and herepandas dataframes 也很好用。

关于你的代码。在 read_data 函数的末尾,您可以组合其中一些 coordinates 语句,并且可能不需要添加 tolist() 因为它是 numpy.array (速度更快并使用更少的内存,请参阅上面的链接)。

在您的 get_bubbles 函数中,我认为您不需要复制数据。副本也会占用内存。我在这里看到的最大问题是在循环中两次使用变量 i 。这很糟糕,因为 i 在第二个循环中被替换了。例如,

for i in [1, 2, 3, 4]:

for i in np.array([5, 6, 7, 8]):
    print(i)

打印5, 6, 7, 8四次。这也很糟糕,因为我们无法判断哪个 i 做了您想要的(没有评论也无济于事 ;) )。将第二个循环中的 i 变量替换为另一个变量,例如 j

这里有两个选项可以使列表更快:列表理解和初始化 numpy.arrays。您可以阅读列表理解 here。初始化 numpy.arrays 的一个例子是

new_data = np.zeros(len(data))

for i in range(len(data)):
     new_data[i] = data[i]

最后,您可以为半径创建一个单独的数组,并考虑使用 numpy.where 到 select 符合您条件的半径索引。

说了这么多,希望对你有帮助。