我是python的新手,所以我会尽力解释我想要做的事情。我试图遍历两个星形列表(两个都包含记录数组),试图通过它们的坐标匹配恒星与公差(在这种情况下Ra和Dec,它们都是记录数组中的索引)。但是,一个列表中似乎有多个星星与另一个星星中的相同星星相匹配。 *这是因为atol中的两个星都匹配。有办法防止这种情况吗?这是我到目前为止所做的:
from __future__ import print_function
import numpy as np
###importing data###
Astars = list()
for s in ApStars:###this is imported but not shown
Astars.append(s)
wStars = list()
data1 = np.genfromtxt('6819.txt', dtype=None, delimiter=',', names=True)
for star in data1:
wStars.append(star)
###beginning matching stars between the Astars and wStars###
list1 = list()
list2 = list()
for star,s in [(star,s) for star in wStars for s in Astars]:
if np.logical_and(np.isclose(s["RA"],star["RA"], atol=0.000277778)==True ,
np.isclose(s["DEC"],star["DEC"],atol=0.000277778)==True):
if star not in list1:
list1.append(star) #matched wStars
if s not in list2:
list2.append(s) #matched Astars
我不能减少atol,因为它超出了乐器错误。会发生什么:有多个Wstars匹配一个Astar。如果有可能的话,我只想要一颗恒星作为明星。
有什么建议吗?
答案 0 :(得分:1)
我会完全改变你的方法以适应这些是你所谈论的天文物体的事实。我将忽略加载功能,并假设您已经有输入列表Astar
和wStar
。
我们会使用笛卡尔点积找到wStar
中Astar
中每颗恒星的最近星。那个应该帮助解决关于最佳匹配的任何含糊之处。
# Pre-process the data a little
def getCV(ra, de):
return np.array([np.cos(aStar['DE']) * np.cos(aStar['RA']),
np.cos(aStar['DE']) * np.sin(aStar['RA']),
np.sin(aStar['DE'])])
for aStar in Astars:
aStar['CV'] = getCV(aStar['RA'], aStar['DE'])
for wStar in wStars:
wStar['CV'] = getCV(wStar['RA'], wStar['DE'])
# Construct lists of matching stars
aList = []
wList = []
# This an extra list of lists of stars that are within tolerance but are
# not best matches. This list will contain empty sublists, but never None
wCandidates []
for aStar in AStars:
for wStar in wStars:
# Use native short-circuiting, and don't explicitly test for `True`
if np.isclose(aStar["RA"], wStar["RA"], atol=0.000277778) and \
np.isclose(aStar["DEC"], wStar["DEC"], atol=0.000277778):
newDot = np.dot(aStar['CV'], wStar['CV'])
if aStar == aList[-1]:
# This star already has a match, possibly update it
if newDot > bestDot:
bestDot = newDot
# Move the previous best match to list of candidates
wCandidates[-1].append(wList[-1])
wList[-1] = wStar
else:
wCandidates[-1].append(wStar)
else:
# This star does not yet have a match
bestDot = newDot
aList.append(aStar)
wList.append(wStar)
wCandidates.append([])
结果是wList
中每个索引处的星号代表aList
中相应星号的最佳匹配。并非所有的星星都有匹配,因此并非所有星星都出现在任何一个列表中。请注意,可能会有一些(非常不可能)的情况,aList
中的星号与wList
中的星号不匹配。
我们通过计算基于these formulas的笛卡尔单位向量并取点积来找到两颗恒星之间最接近的绝对距离。点越接近一个,星星越接近。这应该有助于解决模棱两可的问题。
我为主循环外的星星预先计算了笛卡尔向量,以避免为wStars
反复进行。键名'CV'
代表笛卡尔矢量。根据需要更改它。
最后请注意,此方法不会检查wStars
中的星号是否与多个AStar
匹配。它只是确保为每个wStar
选择最佳AStar
。
<强>更新强>
我在输出中添加了第三个列表,其中列出了对应wStars
元素容差范围内的所有AStars
个候选列表,但没有被选为最佳匹配。
答案 1 :(得分:0)
这里第一次回答问题(如果我犯了错误请注明)。但是大卫评论的内容似乎是正确的,因为“星星总是在列表1中(并且s总是在列表2中”)。 所以我建议比较并附加一个追踪星和星的新列表1 / newlist1。
newlist1 = list()
newlist2 = list()
#new list will keep the unique star and s
for star in list1:
for s in list2:
#assuming the comparison works haven't test it yet
if np.logical_and(np.isclose(s["RA"],star["RA"], atol=0.000277778)==True , np.isclose(s["DEC"],star["DEC"],atol=0.000277778)==True):
if star not in newlist1:
newlist1.append(s)
if s not in newlist2:
newlist2.append(s)
break
#once a match is found leave the second loop
答案 2 :(得分:0)
我还没有完全解决你的问题,但我会首先尝试简化你的计算。
看起来Apstars
和data1
是结构化数组,都是1d,具有相同的dtype
。
此列表迭代可以替换为:
Astars = list()
for s in ApStars:###this is imported but not shown
Astars.append(s)
与
Astarrs = list(ApStars)
或者只是省略。如果你可以在这里迭代ApStars
,你可以在列表理解中迭代它们。与wStars
相同。
我将比较重写为:
set1, set2 = set(), set()
# for star,s in [(star,s) for star in data1 for s in ApStars]:
# iteration on this list comprehension works,
# but I think this nest iteration is clearer
for star in data1:
for s in ApStars:
x1 = np.isclose(s["RA"],star["RA"], atol=0.000277778)
x2 = np.isclose(s["DEC"],star["DEC"],atol=0.000277778)
# isclose returns boolean, don't need the ==True
if x1 & x2:
set1.add(star)
set2.add(s)
set
很容易添加而无需替换,但订单未定义(与dict相同)。
我想探讨在迭代之前“提取”相关字段是否会有所帮助。
Apstars['RA'], data1['RA'], Apstars['DEC'], data1['DEC']
x1 = np.isclose(Apstars['RA'][:,None], data1['RA'], atol=...)
x2 = np.isclose(Apstars['DEC']....)
x12 = x1 & x2
x12
是一个2d布尔数组;当x12[i,j]
“接近”Apstars[i]
时,data1[j]
为True。
答案 3 :(得分:0)
我感谢您提供的所有内容!我做了一些询问,并找到了一个聪明的方法来完成我正在寻找的东西。以下是我们提出的建议:
Route::get('something', ['uses' => 'Controller@page', 'page' => 'something']);
public function page(Request $request)
{
$page = $request->route()->getAction()['page'];
...
}
使用列表理解,计算从Astar到所有wStars的距离,并将所有这些都落在1/3弧秒内。如果一个Astar星有多个wStars匹配,它会附加给出最短距离的Wstar索引及其Astar。