我有一个numpy数组如下:
array([ 90., 180., 270., 360., 450., 540., 630.,
720., 810., 900., 990., 1080., 1170., 1260.,
1350., 1440., 1530., 1620., 1710., 1800., 1890.,
1980., 2070., 2160., 2250., 2340., 2430., 2520.,
2610., 2700., 2790., 2880., 2970., 3060., 3150.,
3240., 3330., 3420., 3510., 3600., 3690., 3780.,
3870., 3960., 4050., 4140., 4230., 4320., 4410.,
4500., 4590., 4680., 4770., 4860., 4950., 5040.,
5130., 5220., 5310., 5400., 5490., 5580., 5670.,
5760., 5850., 5940., 6030., 6120., 6210., 6300.,
6390., 6480., 6570., 6660., 6750., 6840., 6930.,
7020., 7110., 7200., 7290., 7380., 7470., 7560.,
7650., 7740., 7830., 7920., 8010., 8100., 8190.,
8280., 8370., 8460., 8550., 8640., 8730., 8820.,
8910., 9000., 9090., 9180., 9270., 9360., 9450.,
9540., 9630., 9720., 9810., 9900., 9990., 10080.,
10170., 10260., 10350., 10440., 10530., 10620., 10710.,
10800.])
我正在尝试匹配最接近4300或4300的倍数的值。因此,条件语句将在上面的数组中为4320和8640的值返回TRUE,对于所有其他值则返回FALSE。我怎么能做到这一点?
TIA
编辑1:
看了答案之后,我需要澄清一下。我正在寻找最接近+ 20%的值,以返回TRUE。
答案 0 :(得分:3)
您可以使用模运算符和分区运算符执行此操作:
>>> tol = 20
>>> x[x % 4300 <= abs(x // 4300) * tol]
array([ 4320., 8640.])
编辑:
鉴于更新的问题(在特定容差范围内找到最接近的匹配),您正在查看的是最近邻问题的特化。我可能会用scipy的cKDTree这样做,效率最高。例如:
>>> from scipy.spatial import cKDTree
>>> tree = cKDTree(x[:, None])
>>> queries = 4300 * np.arange(np.floor((x / 4300).min()), np.ceil((x / 4300).max()) + 1)
>>> queries
array([ 0., 4300., 8600., 12900.])
>>> d, i = tree.query(queries[:, None], k=1)
>>> x[i]
array([ 90., 4320., 8640., 10800.])
>>> tol = 0.2
>>> x[i][d < tol * x[i]]
array([ 4320., 8640., 10800.])
答案 1 :(得分:1)
如果我正确地阅读了这个问题,请参阅我对@jakevdp的答案的评论,每个倍数只应返回一个值。在这种情况下,您可以通过执行类似
之类的操作来获取索引a = np.arange(0, np.max(x)+4300, 4300)[np.newaxis].T
b = np.zeros(x.shape, dtype=np.bool_)
b[np.argmin(np.abs(a - x), axis=1)] = 1
其中x
是您的输入数组。在给定的示例中,这会产生
array([ True, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, True, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, True, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, True], dtype=bool)
编辑:更新后的问题增加了给定结果在多重范围内的要求。我们可以通过在上面添加额外的步骤来处理这个问题:
a = np.arange(0, np.max(x) + 4300, 4300)[np.newaxis].T
idx = np.argmin(np.abs(a - x), axis=1)
b = np.zeros(x.shape, dtype=np.bool_)
b[idx[np.abs(x[idx] - a.ravel()) < 4300*0.2]] = 1
在这种情况下,b
变为
array([ True, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, True, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, True, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False, False], dtype=bool)
编辑#2给出@ jakevdp答案的评论:要忽略第一个倍数,只需使用
a = np.arange(4300, np.max(x)+4300, 4300)[np.newaxis].T
代替