I have a dataframe that represents several different machine ids, their job number, and the value they output, as follows:
id job value
0 1 1 42
1 1 2 42
2 1 3 42
3 1 4 45
4 2 1 38
5 2 2 38
6 2 3 40
7 2 4 40
8 2 5 42
9 3 1 44
10 3 2 44
11 3 3 43
12 3 4 43
A machine gets each job done in 20 seconds. My goal is to know how many times the value changed per minute. For example, the intermediate step dataframe would be as follows:
id changes
0 1 0 # jobs 1-3=60 seconds. No changes in value
1 1 1 # job 4. Changed from previous value
2 2 1 # jobs 1-3. One change
3 2 1 # jobs 4-5. One change
4 3 1 # jobs 1-3. One change
5 3 0 # job 4. No changes
Then I can easily calculate the end result (change rate per minute) summing the changes column and divide by the number of entries.
id rate
0 1 0.5
1 2 1.0
2 3 0.5
I looked at other questions that partially answer mine, such as this one that uses df.groupby(df.index // 3) to do the bins, but in my case I want that grouping to be per id (groupby(df["id"] // 3)?). And df['changes'] = df.col1 - df.col1.shift()?
Edit to add more test cases:
# Values start at zero to indicate when changes happen
df = pd.DataFrame(
{
"id": [1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3],
"job": [1, 2, 3, 4, 5, 6, 1, 2, 3, 1, 2, 3, 4],
"value": [0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 1, 1, 2]
}
)
Expected result is
1 2.5 # 5 changes total over two minutes
2 0.0 # 0 changes total over one minute
3 1.0 # 2 changes total over a minute and 20 seconds (2 periods)