简体   繁体   English

Python:前向填充列表中的数据

[英]Python: forward fill the data in a list

I have a list named x, I would like to fill the zero data with previous value, which means:我有一个名为 x 的列表,我想用以前的值填充零数据,这意味着:

x = [x[t]=x[t-1] if x[t] == 0.0 for t in range(1,len(x)-2)]

But it displayed: SyntaxError: invalid syntax但它显示: SyntaxError: invalid syntax

I'm wondering where is wrong with my code?我想知道我的代码哪里出了问题? Thanks a lot.非常感谢。

It's your assignment x[t] = x[t-1] . 这是您的任务x[t] = x[t-1] Instead just use a for loop: 而是只使用一个for循环:

for t in range(1, len(x)-1):
    if x[t] == 0:
        x[t] = x[t-1]

Although it would probably be considered more Pythonic to use enumerate to do this: 尽管使用enumerate执行此操作可能被认为更Pythonic:

for idx, val in enumerate(x):
    if idx==0: continue # skip the first element
    if val == 0:
        x[idx] = x[idx-1]

# DEMO

In [1]: x = [1,0,3,0,4,0,5,0]

In [2]: for idx,val in enumerate(x):
   ...:     if idx==0: continue
   ...:     if val == 0:
   ...:         x[idx] = x[idx-1]
   ...:

In [3]: x
Out[3]: [1, 1, 3, 3, 4, 4, 5, 5]

You could also make this work with a list comp by implementing a pairwise iterator 您还可以通过实现成对迭代器来使用list comp进行此操作

from itertools import tee

def pairwise(iterable):
    a,b = tee(iterable)
    next(b) # advance one iterator
    return zip(a,b)

x = [x[0]] + [val if val else lastval for lastval,val in pairwise(x)]

We need to specifically add the first element since the pairwise iterator skips it. 我们需要专门添加第一个元素,因为成对迭代器会跳过它。 Alternatively we could define pairwise differently, eg 或者,我们可以不同地定义pairwise ,例如

def pairwise(iterable):
    iterable = itertools.chain([None], iterable)
    a,b = itertools.tee(iterable)
    next(b)
    return zip(a,b)

x = [val if val else lastval for lastval,val in pairwise(x)]
# ta-da!

Here's a list comprehension to do what you require: 这是您需要执行的列表理解:

x = [xi if xi or i==0 else x[i-1]
     for i, xi in enumerate(x)]

For full forward and backward filling (backwards in case non found before), the following will give you a filled element even if the element before it is zero:对于完全向前和向后填充(如果之前未找到,则向后填充),即使之前的元素为零,以下内容也会为您提供一个填充元素:

#     ∨        ∨        ∨  ∨  ∨     ∨
x = [ 0, 1, 2, 0, 3, 5, 0, 0, 0, 9, 0 ]
y = []
for i,e in enumerate(x):
    if e == 0:
        # search left, get first non zero
        for left_e in reversed(x[:i]):
            if left_e != 0:
                e = left_e
                break
    # backward fill if all elements on the left are zeros 
    if e == 0:
        # search right, get first non zero
        for right_e in x[i+1:]:
            if right_e != 0:
                e = right_e
                break
    y.append(e)
print(y)
# [1, 1, 2, 2, 3, 5, 5, 5, 5, 9, 9]

If you want forward filling with looking only at one the previous element then Alex's answers suffice.如果你想向前填充只看一个前一个元素,那么亚历克斯的答案就足够了。

You can also use a simpler method next():您还可以使用更简单的方法 next():

x = [ 0, 1, 2, 0, 3, 5, 0, 0, 0, 9, 0 ]
y = []
for i,e in enumerate(x):
    if e == 0:
        e = next((item for item in x[i:] if item != 0), e)
        e = next((item for item in reversed(x[:i]) if item != 0), e)
    y.append(e)

print(y)
# [1, 1, 2, 2, 3, 5, 5, 5, 5, 9, 9]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM