在NumPy数组

时间:2017-12-12 16:40:35

标签: python arrays numpy

我有一个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。

2 个答案:

答案 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

代替