我正在使用python
和numpy
来比较两个数组或相等的形状与坐标(x,y,z)以匹配它们,看起来像这样:
coordsCFS
array([[ 0.02 , 0.02 , 0. ],
[ 0.03 , 0.02 , 0. ],
[ 0.02 , 0.025 , 0. ],
...,
[ 0.02958333, 0.029375 , 0. ],
[ 0.02958333, 0.0290625 , 0. ],
[ 0.02958333, 0.0296875 , 0. ]])
和
coordsRMED
array([[ 0.02 , 0.02 , 0. ],
[ 0.02083333, 0.02 , 0. ],
[ 0.02083333, 0.020625 , 0. ],
...,
[ 0.03 , 0.0296875 , 0. ],
[ 0.02958333, 0.03 , 0. ],
[ 0.02958333, 0.0296875 , 0. ]])
使用h5py从两个hdf5文件中读取数据。
为了比较,我使用allclose来测试“几乎相等”。坐标在python的常规浮点精度内不匹配。这就是我使用for循环的原因,否则它会与numpy.where
一起使用。我通常会尽量避免循环,但在这种情况下我无法弄清楚如何。所以我想出了这个令人惊讶的慢速片段:
mapList = []
for cfsXYZ in coordsCFS:
# print cfsXYZ
indexMatch = 0
match = []
for asterXYZ in coordRMED:
if numpy.allclose(asterXYZ,cfsXYZ):
match.append(indexMatch)
# print "Found match at index " + str(indexMatch)
# print asterXYZ
indexMatch += 1
# check: must only find one match.
if len(match) != 1:
print "ERROR matching"
print match
print cfsXYZ
return 1
# save to list
mapList.append(match[0])
if len(mapList) != coordsRMED.shape[0]:
print "ERROR: matching consistency check"
print mapList
return 1
对于我的测试样本大小(800行),这非常慢。我打算比较更大的套装。我可以删除一致性检查并在内部for循环中使用break
以获得一些速度优势。还有更好的方法吗?
答案 0 :(得分:1)
一种解决方案是对两个数组进行排序(添加索引列以使排序的数组仍包含原始索引)。然后,匹配,在锁步中逐步执行数组。由于您期望获得精确的1-1对应关系,因此您应该始终能够将行对匹配。
答案 1 :(得分:1)
首先要记住的是,默认情况下,在NumPy中,“迭代总是以C风格的连续方式进行(最后一个索引变化最快)”[1]。你可以通过颠倒迭代的顺序来改进事物(迭代coordMED.T
,转换coordMED
...)
尽管如此,我仍然对你需要一个循环感到惊讶:你声称'坐标在python的常规浮点精度内不匹配':你是否尝试调整rtol
和{{1} } atol
的参数,如doc?
答案 2 :(得分:1)
你可以用这样的东西摆脱内循环:
for cfsXYZ in coordsCFS:
match = numpy.nonzero(
numpy.max(numpy.abs(coordRMED - cfsXYZ), axis=1) < TOLERANCE)