 # find last non-zero element's index in pandas series

• Last Update :
• Techknowledgy :

I might just write `s[s != 0].index[-1]`, e.g.

```>>> s = pd.Series([0, 1, 2, 3, 0, 4, 0], index = range(7, 14)) >>>
s
7 0
8 1
9 2
10 3
11 0
12 4
13 0
dtype: int64 >>>
s[s != 0].index[-1]
12```

Originally I thought using `nonzero` would make things simpler, but the best I could come up with was

```>>> s.index[s.nonzero()[-1]]
12```

A couple of ways it with generator:

```max(i
for i in s.index
if s[i] != 0) # will work only
if index is sorted```

and

```next(i
for i in s.index[::-1]
if s[i] != 0)```

Through numpy's `trip_zeros`:

```import numpy as np
np.trim_zeros(s, 'b').index[-1]```

Suggestion : 2

Return the integer indices of the elements that are non-zero.,This method is equivalent to calling numpy.nonzero on the series data. For compatibility with NumPy, the return value is the same (a tuple with an array of indices for each dimension), but it will always be a one-item tuple because series only have one dimension.,Indices of elements that are non-zero.,Deprecated since version 0.24.0: Please use .to_numpy().nonzero() as a replacement.

```>>> s = pd.Series([0, 3, 0, 4]) >>>
s.nonzero()
(array([1, 3]), ) >>>
s.iloc[s.nonzero()]
1 3
3 4
dtype: int64```
```>>> s = pd.Series([0, 3, 0, 4], index = ['a', 'b', 'c', 'd'])
# same
return although index of s is different >>>
s.nonzero()
(array([1, 3]), ) >>>
s.iloc[s.nonzero()]
b 3
d 4
dtype: int64```

Suggestion : 3

Last Updated : 30 Sep, 2019

Output:

```(array([0, 2, 3, 5, 6, 8, 9]), )
0 1
2 12
3 1
5 4
6 22
8 3
9 9
dtype: int64```

Suggestion : 4

Returns a tuple of arrays, one for each dimension of a, containing the indices of the non-zero elements in that dimension. The values in a are always tested and returned in row-major, C-style order.,To group the indices by element, rather than dimension, use argwhere, which returns a row for each non-zero element.,Return indices that are non-zero in the flattened version of the input array.,Return the indices of the elements that are non-zero.

```>>> x = np.array([
[3, 0, 0],
[0, 4, 0],
[5, 6, 0]
]) >>>
x
array([
[3, 0, 0],
[0, 4, 0],
[5, 6, 0]
]) >>>
np.nonzero(x)
(array([0, 1, 2, 2]), array([0, 1, 0, 1]))```
```>>> x[np.nonzero(x)]
array([3, 4, 5, 6]) >>>
np.transpose(np.nonzero(x))
array([
[0, 0],
[1, 1],
[2, 0],
[2, 1]
])```
```>>> a = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]) >>>
a > 3
array([
[False, False, False],
[True, True, True],
[True, True, True]
]) >>>
np.nonzero(a > 3)
(array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))```
```>>> a[np.nonzero(a > 3)]
array([4, 5, 6, 7, 8, 9]) >>>
a[a > 3] # prefer this spelling
array([4, 5, 6, 7, 8, 9])```
```>>> (a > 3).nonzero()
(array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))```

Suggestion : 5

Deprecated since version 0.24.0: Please use .to_numpy().nonzero() as a replacement.,Return the integer indices of the elements that are non-zero.,This method is equivalent to calling numpy.nonzero on the series data. For compatibility with NumPy, the return value is the same (a tuple with an array of indices for each dimension), but it will always be a one-item tuple because series only have one dimension.,Indices of elements that are non-zero.

#### Examples

```>>> s = pd.Series([0, 3, 0, 4]) >>>
s.nonzero()
(array([1, 3]), ) >>>
s.iloc[s.nonzero()]
1 3
3 4
dtype: int64```
```>>> s = pd.Series([0, 3, 0, 4])
>>> s.nonzero()
(array([1, 3]),)
>>> s.iloc[s.nonzero()]
1    3
3    4
dtype: int64
```
```>>> s = pd.Series([0, 3, 0, 4], index = ['a', 'b', 'c', 'd'])
# same
return although index of s is different >>>
s.nonzero()
(array([1, 3]), ) >>>
s.iloc[s.nonzero()]
b 3
d 4
dtype: int64```

Suggestion : 6

👻 See our latest reviews to choose the best laptop for Machine Learning and Deep learning tasks! , Pandas Series.nonzero() — it is a method with no arguments. As the name suggests, by returning non-zero values ‚Äã‚Äãfrom a series, it returns the index of all non-zero values. The returned series of indexes can be passed to the method iloc () to return all nonzero values ‚Äã‚Äãat those indices. , As shown in the output, the index position of each nonzero element was returned, and the values ‚Äã‚Äãin this positions were returned by the iloc method. , 👻 Read also: what is the best laptop for engineering students in 2022?

Exit:

` (array([0, 2, 3, 5, 6, 8, 9]), ) 0 1 2 12 3 1 5 4 6 22 8 3 9 9 dtype: int64`

Suggestion : 7

Identify the first & last non-zero elements/indices within a group in numpy,Identify first & last non-zero elements within a group in numpy,Identify first non-zero element within a group in pandas,Identify first non-zero element within group composed of multiple columns in pandas

1._
```group = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2])
array = np.array([1, 2, 3, 0, 0, 2, 0, 3, 4, 0, 0, 0, 0, 1])
targt = np.array([1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1])```

STEP 1. Find indices of nonzero items of `array` and mark the startings of new groups

```nonzero_idx - > [ * 0, 1, 2, /,*/, 5, /,7,8,/, */,/, /,13] (cross out slashes)
marker_idx - > [0, 4, 10]```

STEP 2. Find starting and ending indices for each group, use `np.ufunc.reduceat`

```starts - > [0, 5, 13]
ends - > [2, 8, 13]```

Now, code:

```#STEP 1
nonzero = (array != 0)
_, marker_idx = np.unique(group[nonzero], return_index = True)
nonzero_idx = np.arange(len(array))[nonzero]
#STEP 2
starts = np.minimum.reduceat(nonzero_idx, marker_idx)
ends = np.maximum.reduceat(nonzero_idx, marker_idx)
#STEP 3
values = array[starts]
out = np.zeros_like(array)
out[starts] = values
#check the
case we can 't insert the last negative value
if ends[-1] + 1 == len(array):
out[ends[: -1] + 1] = -values[: -1]
else:
out[ends + 1] = -values >>>
np.cumsum(out)
array([1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1], dtype = int32)```

STEP 1. Find indices of nonzero items of `array` and mark the startings of new groups

```nonzero_idx - > [ * 0, 1, 2, /,*/, 5, /,7,8,/, */,/, /,13] (cross out slashes)
marker_idx - > [0, 4, 10]```

STEP 2. Find starting and ending indices for each group, use `np.ufunc.reduceat`

```starts - > [0, 5, 13]
ends - > [2, 8, 13]```

STEP 3. Think of an `out` array such that `np.cumsum(out)` collapses into `target` array. Like so:

`[1, 0, 0, -1, 0, 2, 0, 0, 0, -2, 0, 0, 0, 1] - > [1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1]`

### 1

```import numpy as np
import pandas as pd

def foo(s):
chk = np.where(s > 0)
start = min(chk)
end = max(chk)
ans = [True
if (start <= ind <= end)
else False
for ind in range(len(s))
]
return ans

pd.Series(array).groupby(group).transform(
lambda x: x.mask(foo(x), x[x > 0].iloc)).to_numpy()
# array([1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1])```

### 2

```def split(val, grp):
inds = np.where(np.append(False, grp[1: ] != grp[: -1]))
return np.array_split(val, inds)

def fill(val):
inds = np.where(val > 0)
start, end = min(inds), max(inds)
val[start: end + 1] = val[start]
return val

np.concatenate([fill(x) for x in split(array, group)])
# array([1, 1, 1, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1])```