1

I have a df containing rows (sometimes thousands) of data, corresponding to a digital signal. I have added an extra column using:

df['On/Off'] = np.where(df[col] > value, 'On', 'Off')

to label the signal as being on or off (value is set depending on the signal source). The following code gives an example dataframe albeit without actual measurement data:

df = pd.DataFrame({"Time/s" : np.arange(0,100,2),
               "On/Off" : ("Off")})
df.at[10:13,"On/Off"] = "On"
df.at[40:43,"On/Off"] = "On"
df.at[47:,"On/Off"] = "On"

I want to count how many times the signal registers as being on. For the above code, the result would be 2 (ideally with an index returned).

Given how the dataframe is organised, I think going down the rows and looking for pairs of rows where column on/off reads as 'off' at row n, then 'on' at row_n+1 should be the approach, as in:

i =0  # <--- number of on/off pairings

if cycle = [row_n]='On'; [row_n+1]='Off':
    i=+1

My current plan came from an answer for this (Pandas iterate over DataFrame row pairs)

I think df.shift() offers a potential route, generating 2 dataframes, and then comparing rows for mismatches, but it feels there could be a simpler way, possibly using itertools, or pd.iterrows (etc.).

As usual, any help is greatly appreciated.

BAC83
  • 811
  • 1
  • 12
  • 27

1 Answers1

1

Use shift with eq (==) for compare values, chain both boolean mask and last count Trues by sum:

out = (df['On/Off'].shift(-1).eq('Off') & df['On/Off'].eq('On')).sum()

Another solution:

out = (df['On/Off'].shift().eq('On') & df['On/Off'].eq('Off')).sum()

print (out )
2

Detail:

print ((df['On/Off'].shift().eq('On') & df['On/Off'].eq('Off')))

0     False
1     False
2     False
3     False
4     False
5     False
6     False
7     False
8     False
9     False
10    False
11    False
12    False
13    False
14     True
15    False
16    False
17    False
18    False
19    False
20    False
21    False
22    False
23    False
24    False
25    False
26    False
27    False
28    False
29    False
30    False
31    False
32    False
33    False
34    False
35    False
36    False
37    False
38    False
39    False
40    False
41    False
42    False
43    False
44     True
45    False
46    False
47    False
48    False
49    False
Name: On/Off, dtype: bool
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252