用于偏移数据列表的算法

时间:2014-02-13 12:43:36

标签: python algorithm

给出如下数据列表:

input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]

我想创建一个能够偏移一定数量步骤列表的算法。例如,如果offset = -1:

def offsetFunc(inputList, offsetList):
    #make something
    return output

其中:

output = [0,0,0,0,1,1,5,5,5,5,5,5,3,3,3,2,2]

重要提示:列表中的元素是浮点数,它们没有任何进展。所以我实际上需要转移它们,我不能使用任何解决方法来获得结果。

所以基本上,算法应该用0替换第一组值(基本上是4“1”)然后它应该:

  1. 检测下一个值范围的长度
  2. 创建一个延迟一组的并行输出向量
  3. 我粗略描述上述算法的方式就是我如何做到这一点。然而,我是Python的新手(甚至是普通编程的初学者),我已经及时发现Python有很多内置函数可以使算法减少繁重和迭代。有没有人有任何建议可以更好地开发脚本来完成这种工作?这是我到目前为止编写的代码(假设静态偏移量为-1):

    input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
    output = []
    PrevVal = 0
    NextVal = input[0]
    i = 0
    while input[i] == NextVal:
        output.append(PrevVal)
        i += 1
    
    while i < len(input):    
        PrevVal = NextVal
        NextVal = input[i]
        while input[i] == NextVal:
            output.append(PrevVal)
            i += 1
            if i >= len(input):
                break
    
    print output
    

    提前感谢您的帮助!

    更好的描述 我的列表将始终由值的“集合”组成。它们通常是浮点数,它们采用的值如下面这个简短的例子:

    Sample = [1.236,1.236,1.236,1.236,1.863,1.863,1.863,1.863,1.863,1.863]
    

    在这个例子中,第一个集合(值为“1.236”的集合)是长4而第二个集合是长6.当offset = -1时,我希望得到的输出是:< / p>

    1. 前4个元素中的值“0.000”;
    2. 第二个6个元素中的值“1.236”。
    3. 所以基本上,这个“偏移”函数创建的列表具有相同的“结构”(长度范围),但值延迟了“偏移”次

      我希望现在很清楚,不幸的是问题本身对我来说仍然有点傻(加上我甚至不会说英语:)) 请不要犹豫,提出任何其他信息来完成问题并使其更清晰。

5 个答案:

答案 0 :(得分:6)

这个怎么样:

def generateOutput(input, value=0, offset=-1):
  values = []
  for i in range(len(input)):
    if i < 1 or input[i] == input[i-1]:
      yield value
    else:  # value change in input detected
      values.append(input[i-1])
      if len(values) >= -offset:
        value = values.pop(0)
      yield value

input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
print list(generateOutput(input))

它会打印出来:

[0, 0, 0, 0, 1, 1, 5, 5, 5, 5, 5, 5, 3, 3, 3, 2, 2]

如果你只想迭代,你甚至不需要构建列表。然后使用for i in generateOutput(input): …

对于其他偏移,请使用:

print list(generateOutput(input, 0, -2))

打印:

[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 5, 5, 5, 3, 3]

答案 1 :(得分:2)

使用deque作为队列,并使用maxlen定义移位长度。只持有唯一值。最后推送inn值,在队列开始时推出旧值,当达到移位长度时。

from collections import deque

def shift(it, shift=1):
    q = deque(maxlen=shift+1)
    q.append(0)
    for i in it:
        if q[-1] != i:
            q.append(i)
        yield q[0]


Sample = [1.236,1.236,1.236,1.236,1.863,1.863,1.863,1.863,1.863,1.863]

print list(shift(Sample))
#[0, 0, 0, 0, 1.236, 1.236, 1.236, 1.236, 1.236, 1.236]

答案 2 :(得分:2)

我的尝试:

#Input
input = [1,1,1,1,5,5,3,3,3,3,3,3,2,2,2,5,5]
shift = -1

#Build service structures: for each 'set of data' store its length and its value
set_lengths = []
set_values = []

prev_value = None
set_length = 0
for value in input:
    if prev_value is not None and value != prev_value:
        set_lengths.append(set_length)
        set_values.append(prev_value)
        set_length = 0
    set_length += 1
    prev_value = value
else:
    set_lengths.append(set_length)
    set_values.append(prev_value)

#Output the result, shifting the values
output = []
for i, l in enumerate(set_lengths):
    j = i + shift 
    if j < 0:
        output += [0] * l
    else:
        output += [set_values[j]] * l

print input
print output

给出:

[1, 1, 1, 1, 5, 5, 3, 3, 3, 3, 3, 3, 2, 2, 2, 5, 5]
[0, 0, 0, 0, 1, 1, 5, 5, 5, 5, 5, 5, 3, 3, 3, 2, 2]

答案 3 :(得分:1)

def x(list, offset):
    return [el + offset for el in list]

答案 4 :(得分:1)

与我的第一个答案完全不同的是:

import itertools

首先分析输入:

values, amounts = zip(*((n, len(list(g))) for n, g in itertools.groupby(input)))

我们现在有(1, 5, 3, 2, 5)(4, 2, 6, 3, 2)。现在应用偏移量:

values = (0,) * (-offset) + values  # nevermind that it is longer now.

再次合成:

output = sum([ [v] * a for v, a in zip(values, amounts) ], [])

这种方式更优雅,更难理解,可能比我的其他答案更昂贵,但我不想把它藏起来。