I have a dataframe with a row with integers such as
value
0
0
0
0
1
2
0
3
0
2
5
6
0
0
0
Is there a way that I can eliminate the first 0s and last 0s (but not the ones in the middle) to get
1
2
0
3
0
2
5
6
I have a dataframe with a row with integers such as
value
0
0
0
0
1
2
0
3
0
2
5
6
0
0
0
Is there a way that I can eliminate the first 0s and last 0s (but not the ones in the middle) to get
1
2
0
3
0
2
5
6
Create mask and filter all non 0
values after first match by Series.cummax
and chain reversed order of condition for eliminate last 0
by &
for bitwise AND
with filter in boolean indexing
:
m = df['value'].ne(0)
out = df[m.cummax() & m.iloc[::-1].cummax()]
print (out)
value
4 1
5 2
6 0
7 3
8 0
9 2
10 5
11 6
Not sure whether this is an efficient solution since i'm finding the first non zero value and the last non zero value independently and then extracting only the values between them, but it works. But @jezrael's one looks slick:
import pandas as pd
df = pd.DataFrame({
'col': [0, 0, 0, 0, 1, 2, 0, 3, 0, 2, 5, 6, 0, 0, 0],
})
# Remove leading and trailing 0s from the 'col' column
first_nonzero = next((i for i, x in enumerate(df['col']) if x > 0), None)
last_nonzero = next((i for i, x in enumerate(df['col'][::-1]) if x), None)
last_nonzero = len(df) - last_nonzero if last_nonzero is not None else None
df = df.iloc[first_nonzero:last_nonzero]
df = df.reset_index(drop=True)
print(df)
Resetting the index of the dataframe is optional.