我想对无序的复杂花车的numpy数组进行鼻子测试。
例如,如果
a = [1+1j, 1-1j, 2+2j, 2-2j, 2+2j, 2-2j]
和
b = [2+2j, 2-2j, 1+1j, 1.000000000000001-1j, 2+2j, 2-2j]
断言应该成功,因为它们具有大致相同的值相同的次数。订单无关紧要。
对于常规浮点数,assert_array_almost_equal(np.sort(a), np.sort(b))
会没问题,但是这在这里不起作用,因为它先按实部按虚数部分进行排序,因此浮动错误将它们排序为:
a: [ 1.-1.j, 1.+1.j, 2.-2.j, 2.-2.j, 2.+2.j, 2.+2.j]
b: [ 1.+1.j, 1.-1.j, 2.-2.j, 2.-2.j, 2.+2.j, 2.+2.j]
有没有内置的方法来做到这一点?如果没有,我想我可以使用类似cplxreal的东西,但这似乎可以添加到测试文件中。
答案 0 :(得分:2)
如何根据数量对数组进行排序?
def foo(a):
return a[np.argsort(a*a.conjugate())]
np.testing.assert_array_almost_equal(foo(a),foo(b))
答案 1 :(得分:0)
我不确定是否有任何方法可以在比O(n^2)
最差情况更好的情况下执行此操作,但如果您可以接受,则可以复制其中一个列表并使用修改后的{{1}消除函数以查看它们是否匹配。
equals
然后遍历您的列表,在找到匹配项时删除匹配
def equals(a, b, tolerance):
return abs(a-b) < tolerance
似乎在最初的情况下工作,至少是粗略的:
def equivalent_lists(a, b, tolerance):
new_b = b[:]
for a_item in a:
truths = [equals(a_item, b_item, tolerance) for b_item in new_b]
if not any(truths):
return False
else:
new_b.pop(truths.index(True))
return not bool(new_b)
不是最美丽的解决方案,但至少似乎以一种非常透明的方式工作。
答案 2 :(得分:0)
另一种方法可能是考虑二维空间中的点数。 a
是一组点。 b
是另一套。 b
中的每个点都应该接近a
中的一个点。
diff = np.array(a)[None,:]-np.array(b)[:,None]
X = np.round(diff*diff.conjugate())==0 # round to desired error tollerance
X
array([[False, False, True, False, True, False],
[False, False, False, True, False, True],
[ True, False, False, False, False, False],
[False, True, False, False, False, False],
[False, False, True, False, True, False],
[False, False, False, True, False, True]], dtype=bool)
下一步是测试X
。如果a
(和b
)中的值不同,则每列和每行应该有一个True
。但这里有重复。
In [29]: I,J=np.where(X)
In [30]: I
Out[30]: array([0, 0, 1, 1, 2, 3, 4, 4, 5, 5])
In [31]: J
Out[31]: array([2, 4, 3, 5, 0, 1, 2, 4, 3, 5])
set(I)
和set(J)
都是[0,1,.. 5],因此所有行和列都匹配。即使有重复项,此设置测试也可能足够。我必须探索其他点和不匹配的组合。
这个答案不完整,但可能提供一些有用的想法。