简体   繁体   中英

Pandas Series: How to get the nth non-zero element before each element

I have a pandas series like this:

[0,3,4,5,0,0,2,4,5]

For each element, I want to be able to get the nth non-zero element before it.

The output Series for the above input Series would be

n=1
[NaN,NaN,3,4,5,5,5,2,4]

n=2
[NaN,NaN,NaN,3,4,4,4,5,2]

etc.

Is there a built in way in pandas to do this easily?

You can use rolling and apply to extract the nth non zero elements from the rolling window.

First we use rolling(len(s)) which gives a rolling 9 rows window until the current row for each row. Then we remove 0s from the rolling window. x[:-1] is to exclude the current row because we need to find the non-zero element before it. Finally, we extract the nth element from the non-zero list by doing [-n].

n=1
s.rolling(len(s),min_periods=0)\
 .apply(lambda x: x[:-1][x[:-1]!=0][-n] if len(x[:-1][x[:-1]!=0])>=n else np.nan)
Out[97]: 
0    NaN
1    NaN
2    3.0
3    4.0
4    5.0
5    5.0
6    5.0
7    2.0
8    4.0
dtype: float64

n=2    
s.rolling(len(s),min_periods=0)\
 .apply(lambda x: x[:-1][x[:-1]!=0][-n] if len(x[:-1][x[:-1]!=0])>=n else np.nan)
Out[99]: 
0    NaN
1    NaN
2    NaN
3    3.0
4    4.0
5    4.0
6    4.0
7    5.0
8    2.0
dtype: float64
def dew(zoop, n):
  x = zoop.pop()
  zoop.reverse()
  for i in range(len(zoop)):
    if not zoop[i] == 0:
      n -= 1
      if n == 0:
        return zoop[i]
  return float('NaN')

lzt = [0,3,4,5,0,0,2,4,5]
ans = []
for i in range(len(lzt)):
  ans.append(dew(lzt[:i+1], 2)) #2 is n here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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