繁体   English   中英

Python:如何将list / array / pd.Series中的零值设置为下一个非零值?

[英]Python: How to set values of zero in a list/array/pd.Series to be the next non-zero value?

我有一个类似Python列表的结构,包含超过一百万个元素。 每个元件采取的三个可能的值之一,即-10 ,或1 我试图实现的是用下一个非零值替换所有零。

例如,如果我有

[1, 0, 0, -1, 0, 1, 0, 0, 0, -1]

手术后我会

[1,-1,-1,-1,1,1,-1,-1,-1,-1]。

我可以有一个嵌套的循环结构来实现此目标,但是列表中有超过一百万个元素,因此要花很多时间才能运行。 有谁知道可以实现此目标的更快算法?

您可以尝试首先创建Series ,然后replace 0 replaceNaN ,最后使用fillna

import pandas as pd
import numpy as np

li = [1, 0, 0, -1, 0, 1, 0, 0, 0, -1]
s = pd.Series(li)
print s
0    1
1    0
2    0
3   -1
4    0
5    1
6    0
7    0
8    0
9   -1
dtype: int64


print s.replace({0:np.nan})
0     1
1   NaN
2   NaN
3    -1
4   NaN
5     1
6   NaN
7   NaN
8   NaN
9    -1
dtype: float64
print s.replace({0:np.nan}).fillna(method='bfill')
0    1
1   -1
2   -1
3   -1
4    1
5    1
6   -1
7   -1
8   -1
9   -1
dtype: float64

或者replace使用use loc ,然后按astype转换为int,最后使用tolist

s.loc[s == 0] = np.nan

s.loc[s == 0] = np.nan
print s.fillna(method='bfill').astype(int).tolist()
[1, -1, -1, -1, 1, 1, -1, -1, -1, -1]

这是一个纯Python解决方案。

创建一个保留先前值状态的小类,并将当前值与此先前值进行比较。

class Checker:
    def _compare(self, val):
        if val or not self.prior:
            self.prior = val
            return val
        return self.prior
    def reverse_fill_list(self, some_list):
        self.prior = None
        return [self._compare(v) for v in some_list[::-1]][::-1]

然后以相反的顺序对列表使用列表推导(使用[::-1]进行反向)。 然后再次反转结果以恢复原始顺序。

some_list = [1, 0, 0, -1, 0, 1, 0, 0, 0, -1]
c = Checker()  # Instantiate object.

>>> c.reverse_fill_list(some_list)
[1, -1, -1, -1, 1, 1, -1, -1, -1, -1]


np.random.seed(0)
# Create one million values in range [-1, 0, 1].
a = np.random.random_integers(-1, 1, 1000000)
>>> a[:10]
array([-1,  0, -1,  0,  0,  1, -1,  1, -1, -1])

%timeit c.reverse_fill_list(a)
1 loops, best of 3: 311 ms per loop

使用Pandas的结果更快(使用@Jezrael的解决方案)。

>>> pd.Series(a).replace({0:np.nan}).fillna(method='bfill').tolist()
10 loops, best of 3: 136 ms per loop

您可以从头开始进行迭代。 这将是一个On )解。

a=[0,1,0,0,0,0,-1,0];
length=len(a);
length=length-1;
//Assuming if last value is 0 you just let it be and the 0s before it.
val=0;
print a
for i in range(length):
    if (a[length-i] != 0):
        val=a[length -i];
    else:
        a[length-i]=val;
    i=i+1;
print a
exit();

好吧while如果您想使用纯Python,则可以使用一个简单的while循环:

li=[1, 0, 0, -1, 0, 1, 0, 0, 0, -1]
i=len(li)-1
while i:
    if li[i]:
        val=li[i]
    else:
        li[i]=val
    i-=1    

>>> li
[1, -1, -1, -1, 1, 1, -1, -1, -1, -1] 

假定最后一个值为1或-1,但是您未指定最终值可能会欺骗您。

暂无
暂无

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

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