如何使用numpy比较任何值是否与其他值相似

时间:2019-06-14 21:04:12

标签: python numpy

我有很多这样的坐标数组对

a=[(1.001,3),(1.334, 4.2),...,(17.83, 3.4)]
b=[(1.002,3.0001),(1.67, 5.4),...,(17.8299, 3.4)]
c=[(1.00101,3.002),(1.3345, 4.202),...,(18.6, 12.511)]

任何对中的任何坐标都可以是另一个对数组中另一个坐标的副本。数组的大小也不相同。

重复项的值会略有不同,例如,我将a,b和c中的第一个值视为重复项。

我可以遍历每个数组,并使用numpy.isclose逐个比较值,但这会很慢。

是否有一种有效的方法来解决此问题,希望使用numpy来保持较低的计算时间?

3 个答案:

答案 0 :(得分:0)

您可能想尝试round()函数,该函数会将列表中的数字四舍五入为最接近的整数。 我建议的下一件事情可能太极端了:

合并数组并将其放入pandas数据框和drop_duplicates()

这可能不是您想要的解决方案

答案 1 :(得分:0)

如果允许AsertionError处理,您可能想看看numpy.testing。

from numpy import testing as ts

a = np.array((1.001,3))
b = np.array((1.000101, 3.002))

ts.assert_array_almost_equal(a, b, decimal=1)  # output None

但是

ts.assert_array_almost_equal(a, b, decimal=3)

结果

AssertionError: 
Arrays are not almost equal to 3 decimals
Mismatch: 50%
Max absolute difference: 0.002
Max relative difference: 0.00089891
 x: array([1.001, 3.   ])
 y: array([1.   , 3.002])

numpy.testing还有一些更有趣的功能。确保查看the docs

答案 2 :(得分:0)

我正在使用pandas为您提供直观的结果,而不仅仅是数字。当然,您可以根据需要扩展解决方案

假设您从每个数组创建一个pd.DataFrame,并标记每个数组所属的数组。我将结果四舍五入到小数点后两位,您可以根据需要使用任意公差

dfa = pd.DataFrame(a).round(2)
dfa['arr'] = 'a'

然后,通过串联,使用duplicated进行排序,您可能会发现一个直观的数据框可以满足您的需求

df = pd.concat([dfa, dfb, dfc])

df[df.duplicated(subset=[0,1], keep=False)].sort_values(by=[0,1])

收益

    x       y   arr
0   1.00    3.0 a
0   1.00    3.0 b
0   1.00    3.0 c
1   1.33    4.2 a
1   1.33    4.2 c
2   17.83   3.4 a
2   17.83   3.4 b

索引是重复的,因此您可以简单地在末尾使用reset_index()并将新生成的列用作指示每个数组上相应索引的参数。即:

    index   x       y   arr
0   0       1.00    3.0 a
1   0       1.00    3.0 b
2   0       1.00    3.0 c
3   1       1.33    4.2 a
4   1       1.33    4.2 c
5   2       17.83   3.4 a
6   2       17.83   3.4 b

例如,第0行表示重复的坐标,位于index arr的{​​{1}} 0上。第1行还表示一个重复坐标,在a index中找到了arr 0,等等。


现在,如果您只想删除重复项并获得仅包含非重复值的一个最终数组,则可以使用b

drop_duplicates

产生

df.drop_duplicates(subset=[0,1])[[0,1]].to_numpy()