多数过滤python

时间:2016-10-03 10:42:45

标签: python filtering

我正在尝试创建一个函数,该函数将使用在x个元素的给定框架内与其相邻的最大次数的值替换列表元素。

Eg-

  • A = [2,2,2,3,2,1,4,4,4,4,5,5,5,5,6,7,7,7,8,8,8 ,8]

  • 如果x = 5,修改后的清单应为 - A = [2,2,2,2,2,4,4,4,4,4,5,5,5,5,5,7,7,7,8,8,8,8]

我已经完成了天真的滑动窗口实现。 是否有内置函数或 pythonic 方法来执行此操作?

1 个答案:

答案 0 :(得分:3)

这是一个天真的滑动窗口1D多数过滤器的三个实现。

第一个使用"传统" for循环,第二个实际上是相同的算法,但在列表理解中使用生成器表达式。这些都使用

确定给定窗口中的多数元素
max(set(a), key=a.count)

其中a是窗口。我们首先创建一个集合以获取a中的唯一元素,然后在a中查找哪些元素具有最高计数。

第三个版本使用collections.Counter(增强字典)来查找多数元素。

#!/usr/bin/env python3

from collections import Counter

def majority_filter_traditional(seq, width):
    offset = width // 2
    seq = [0] * offset + seq
    result = []
    for i in range(len(seq) - offset):
        a = seq[i:i+width]
        result.append(max(set(a), key=a.count))
    return result

def majority_filter_listcomp(seq, width):
    offset = width // 2
    seq = [0] * offset + seq
    return [max(set(a), key=a.count) 
        for a in (seq[i:i+width] for i in range(len(seq) - offset))]

def majority_filter_counter(seq, width):
    offset = width // 2
    seq = [0] * offset + seq
    return [Counter(a).most_common(1)[0][0]
        for a in (seq[i:i+width] for i in range(len(seq) - offset))]

majority_filter = majority_filter_listcomp

seq = [2, 2, 2, 3, 2, 1, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7, 7, 7, 8, 8, 8, 8]
print(seq)
print(majority_filter(seq, 5))

<强>输出

[2, 2, 2, 3, 2, 1, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7, 7, 7, 8, 8, 8, 8]
[2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 7, 7, 7, 8, 8, 8, 8]

上面的代码也适用于Python 2. Counter类不在Python 2.7之前的版本的标准库中,但有code available for Counter可用于Python 2.5。