1

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
KansaiRobot
  • 7,564
  • 11
  • 71
  • 150

2 Answers2

1

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
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
0

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)

Output: enter image description here

Resetting the index of the dataframe is optional.

Kulasangar
  • 9,046
  • 5
  • 51
  • 82