【问题标题】:Calculate neighbor values in array计算数组中的相邻值
【发布时间】:2015-09-12 17:02:06
【问题描述】:

给定一个元组列表,[(x1, y1), (x2, y2) ... (xm, ym)] 例如[(1, 2), (3, 7), (5, 9)] 我想写一个函数,用相邻值的平均值 f(x - 1), f(x + 1).

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

[(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) ... ]

有点复杂:

[(1, 2), (2, ave(prev, next_that_exists)), (3, ave(just_created, next_that exists), ...]

我该如何实现,以便我们找到刚好低于缺失元素和高于缺失元素的元素,并计算它们的平均值?

另外,这与移动平均线有什么不同吗?

【问题讨论】:

  • 您的缩进不正确。请帮助我们修复它。
  • 如果 xs = [1, 4, 7] 你希望答案是什么?
  • 这其实很有趣。在间隙为 2 的情况下,您基本上有 2, a, b, 7 其中 a = (2 + b)/2b = (a+7)/2 - 两个具有两个未知数的方程。间隔为 3,您有 2, a, b, c, 7a = (2+b)/2 等... - 三个方程和三个未知数。我试图想出一个优雅的方法来解决这个问题,但还没有。

标签: python average neighbours


【解决方案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 where

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)。那时我意识到,通过想要在较大的间隙中填充相邻值的平均值,您基本上需要在给定的步数上从一个值到下一个值的线性插值。也就是说,例如,假设您想在3 步骤中从2 转到7,则将5/3 重复添加到2,直到您到达7

【讨论】:

    【解决方案2】:

    这是我的方法:从输入中创建一个字典,其中第一个列表作为键,第二个列表作为值。然后创建一个函数,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 值的列表。

    【讨论】:

    • 这会在nearest([1, 4, 7], [3, 4, 5])上产生一个无限循环
    • 垃圾进,垃圾出。 1 和 4 之间有一个空白,原始海报没有说明如何填补这个空白。现在 OP 已经发布了要求的更新。我正在努力更新我的解决方案。
    • 他确实没有详细说明,但他要求提供专门解决这种情况的代码 - 似乎他的代码已经处理了非间隙情况。
    猜你喜欢
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多