计算数组中的邻居值

时间:2015-09-12 17:02:07

标签: python average neighbours

给定一个元组列表 angular.directive('myDirective', [function($document) { return { restrict:'E', link: function(scope, element, attribute) { var parent = element.parent();// will give an array var parentWidth = parent[0].offsetWidth; //modify/truncate your attribute.value depending upon the parentWidth. } } }]); ,例如[(x1, y1), (x2, y2) ... (xm, ym)]我想编写一个函数,用邻居值f(x - 1)的平均值填充缺失的整数值x, f(x + 1)。

在这种情况下,我们会得到:

[(1, 2), (3, 7), (5, 9)]

[(1, 2), (2, ave(2, 7)), (3, 7), (4, ave(7, 9)), (5, 9)]

然而,使用import numpy as np # calculating nearest neighbor averages def nearest(x, y): # define the min and max for our line min = np.amin(x) max = np.amax(x) # fill in the gaps numsteps = max - min + 1 # an empty vessel new_df = [] # an empty vessel for our xs xs = np.linspace(min, max, numsteps) for i, item in enumerate(xs): if(xs[i] in x): idx = x.index(xs[i]) new_df.insert(i, (xs[i], y[idx])) else: idx = x.index(xs[i] - 1) idx2 = x.index(xs[i] + 1) avg = (y[idx] + y[idx2])/2.0 new_df.insert(i, (xs[i], avg)) print new_df nearest([1, 3, 5], [6, 7, 8]) // [(1.0, 6), (2.0, 6.5), (3.0, 7), (4.0, 7.5), (5.0, 8)] 之类的数组很快就会失败,因为这些值彼此相距不止一个。在这种情况下,给定相同的xs = [1, 4, 7],我们希望答案是:

ys = [2, 7, 9]

有点复杂:

[(1, 2), (2, ave(2, 7)), (3, ave(2,7)), (4, 7) ... ]

我如何实施,以便我们找到丢失的元素正下方的元素,并在缺失的元素上方,并计算它们的平均值?

此外,这与移动平均线不同吗?

2 个答案:

答案 0 :(得分:1)

这是我的方法:从输入中创建一个字典,第一个列表作为键,第二个列表作为值。然后创建一个函数get_value()来获取值,并在需要时计算它。

def get_value(pairs, key):
    try:
        return pairs[key]
    except KeyError:
        previous_value = get_value(pairs, key -1)
        next_value = get_value(pairs, key + 1)
        return (previous_value + next_value) / 2.0

def nearest(x, y):
    pairs = dict(zip(x, y))
    for i in range(1, max(x) + 1):
        yield i, get_value(pairs, i)

print list(nearest([1, 3, 5], [6, 7, 8]))

更新

我现在有机会重温这个问题。根据您的描述,您希望插入缺失值。既然您已经安装了numpy,为什么不使用它呢?

import numpy as np

def nearest(x, y):
    all_x = range(min(x), max(x) + 1)
    return zip(all_x, np.interp(all_x, x, y))

print nearest([1, 3, 5], [6, 7, 8])
print nearest([1, 4, 7], [6, 7, 8])

输出:

[(1, 6.0), (2, 6.5), (3, 7.0), (4, 7.5), (5, 8.0)]
[(1, 6.0), (2, 6.333333333333333), (3, 6.666666666666667), (4, 7.0), (5, 7.333333333333333), (6, 7.666666666666667), (7, 8.0)]

numpy.interp完成所有繁重的工作,最近的函数只需要找出所有x值的列表。

答案 1 :(得分:1)

这应该有效:

def nearest(x, y):
    assert len(x) == len(y)

    res = []
    for i in xrange(len(x)-1):
        res.append((x[i], y[i]))
        gap = x[i+1] - x[i]
        for j in xrange(1, gap):
            res.append((x[i]+j, y[i] + j * (y[i+1]-y[i]) / float(gap)))
    res.append((x[-1], y[-1]))

    return res

示例输出

print nearest([1, 3, 5], [2, 7, 9])
print nearest([1, 4, 7], [2, 7, 9])

给出:

[(1, 2), (2, 4.5), (3, 7), (4, 8.0), (5, 9)]
[(1, 2), (2, 3.666666666666667), (3, 5.333333333333334), (4, 7), (5, 7.666666666666667), (6, 8.333333333333334), (7, 9)]

<强>解释

我手动解决了[1, 4][2, 7]案例,并指出我们想要的值是2, x, y, 7其中

x = (2 + y) / 2
y = (x + 7) / 2

我得到了x = 11/3y = 16/3,产生了:

6/3, 11/3, 16/3, 21/3

请注意,每个版本之间的差距为5/3(7-2) / (4-1)。那时我意识到,想要在较大的间隙中填充邻居值的平均值,您基本上需要在给定的步数内从一个值到下一个值进行线性插值。也就是说,例如,如果您希望在2步骤中从7转到3,则会反复将5/3添加到2,直到您到{ {1}}。