将值列表舍入到python中另一个列表中最接近的值

时间:2015-10-31 09:54:04

标签: python algorithm numpy

假设我有以下两个数组:

>>> a = np.random.normal(size=(5,))
>>> a
array([ 1.42185826,  1.85726088, -0.18968258,  0.55150255, -1.04356681])

>>> b = np.random.normal(size=(10,10))
>>> b
array([[ 0.64207828, -1.08930317,  0.22795289,  0.13990505, -0.9936441 ,
         1.07150754,  0.1701072 ,  0.83970818, -0.63938211, -0.76914925],
       [ 0.07776129, -0.37606964, -0.54082077,  0.33910246,  0.79950839,
         0.33353221,  0.00967273,  0.62224009, -0.2007335 , -0.3458876 ],
       [ 2.08751603, -0.52128218,  1.54390634,  0.96715102,  0.799938  ,
         0.03702108,  0.36095493, -0.13004965, -1.12163463,  0.32031951],
       [-2.34856521,  0.11583369, -0.0056261 ,  0.80155082,  0.33421475,
        -1.23644508, -1.49667424, -1.01799365, -0.58232326,  0.404464  ],
       [-0.6289335 ,  0.63654201, -1.28064055, -1.01977467,  0.86871352,
         0.84909353,  0.33036771,  0.2604609 , -0.21102014,  0.78748329],
       [ 1.44763687,  0.84205291,  0.76841512,  1.05214051,  2.11847126,
        -0.7389102 ,  0.74964783, -1.78074088, -0.57582084, -0.67956203],
       [-1.00599479, -0.93125754,  1.43709533,  1.39308038,  1.62793589,
        -0.2744919 , -0.52720952, -0.40644809,  0.14809867, -1.49267633],
       [-1.8240385 , -0.5416585 ,  1.10750423,  0.56598464,  0.73927224,
        -0.54362927,  0.84243497, -0.56753587,  0.70591902, -0.26271302],
       [-1.19179547, -1.38993415, -1.99469983, -1.09749452,  1.28697997,
        -0.74650318,  1.76384156,  0.33938808,  0.61647274, -0.42166111],
       [-0.14147554, -0.96192206,  0.14434349,  1.28437894, -0.38865447,
        -1.42540195,  0.93105528,  0.28993325, -1.16119916, -0.58244758]])

我必须找到一种方法将所有值从b四舍五入到a中找到的最近值。

有没有人知道用python做这个的好方法?我自己完全失去了。

4 个答案:

答案 0 :(得分:0)

如果你排序a,你可以使用bisect来查找数组a中的索引,其中数组b的子数组中的每个元素都将落地:

import numpy as np
from bisect import bisect


a = np.random.normal(size=(5,))

b = np.random.normal(size=(10, 10))
a.sort()
size = a.size


for sub in b:
    for ind2, ele in enumerate(sub):
        i = bisect(a, ele, hi=size-1)
        i1, i2 = a[i], a[i-1]
        sub[ind2] = i1 if abs(i1 - ele) < abs(i2 - ele) else i2

答案 1 :(得分:0)

这是您可以尝试的

import numpy as np

def rounder(values):
    def f(x):
        idx = np.argmin(np.abs(values - x))
        return values[idx]
    return np.frompyfunc(f, 1, 1)

a = np.random.normal(size=(5,))
b = np.random.normal(size=(10,10))
rounded = rounder(a)(b)
print(rounded)

rounder函数采用我们要舍入的值。它创建一个函数,该函数采用标量并返回values数组中最接近的元素。然后,我们使用numpy.frompyfunc将此功能转换为可广播的功能。这样,您不仅可以在2d数组上使用它,numpy还会自动为您进行广播,而不会产生任何循环。

答案 2 :(得分:0)

假设a始终为一维,并且b在此解决方案中可以具有任何尺寸。

创建两个临时数组,将ab拼接成另一个维度(此处,两者的形状现在为(5,10,10))。

at = np.tile(np.reshape(a, (-1, *list(np.ones(len(b.shape)).astype(int)))), (1, *b.shape))
bt = np.tile(b, (a.size, *list(np.ones(len(b.shape)).astype(int))))

对于最近的运算,您可以获取两者之差的绝对值。该操作在第一维(维度0)中的最小值给出了a数组中的索引。

idx = np.argmin(np.abs(at-bt),axis=0)

剩下的就是使用索引从数组a中选择值,这将返回b形状的数组,其中的值与a中的值最接近。

ans = a[idx]

也可以使用此方法(修改索引的计算方式)执行其他操作,例如地板,天花板等。

请注意,此解决方案可能会占用大量内存,这对于小型阵列来说并不是什么大问题。循环解决方案可能会降低速度,降低内存密集度。

答案 3 :(得分:-1)

我不知道Numpy,但我不认为Numpy的知识需要能够回答这个问题。假设可以以与列表相同的方式迭代和修改数组,以下代码通过使用嵌套循环来查找最接近的值来解决您的问题。

for i in range(len(b)):
    for k in range(len(b[i])):
        closest = a[0]
        for j in range(1, len(a)):
            if abs(a[j] - b[i][k]) < abs(closest - b[i][k]):
                closest = a[j]
        b[i][k] = closest

免责声明:可能存在更多的pythonic方法。