[英]Python: How to set values of zero in a list/array/pd.Series to be the next non-zero value?
我有一个类似Python列表的结构,包含超过一百万个元素。 每个元件采取的三个可能的值之一,即-1
, 0
,或1
。 我试图实现的是用下一个非零值替换所有零。
例如,如果我有
[1, 0, 0, -1, 0, 1, 0, 0, 0, -1]
手术后我会
[1,-1,-1,-1,1,1,-1,-1,-1,-1]。
我可以有一个嵌套的循环结构来实现此目标,但是列表中有超过一百万个元素,因此要花很多时间才能运行。 有谁知道可以实现此目标的更快算法?
您可以尝试首先创建Series
,然后replace
0
replace
为NaN
,最后使用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
您可以从头开始进行迭代。 这将是一个O ( n )解。
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.