Tomasz
Tomasz

Reputation: 568

Incrementing add under condition in pandas

For the following pandas dataframe

    servo_in_position   second_servo_in_position    Expected output
0   0   1   0
1   0   1   0
2   1   2   1
3   0   3   0
4   1   4   2
5   1   4   2
6   0   5   0
7   0   5   0
8   1   6   3
9   0   7   0
10  1   8   4
11  0   9   0
12  1   10  5
13  1   10  5
14  1   10  5
15  0   11  0
16  0   11  0
17  0   11  0
18  1   12  6
19  1   12  6
20  0   13  0
21  0   13  0
22  0   13  0

I want to increment the column "Expected output" only if "servo_in_position" changes from 0 to 1. I want also to assume "Expected output" to be 0 (null) if "servo_in_position" equals to 0.

I tried

input_data['second_servo_in_position']=(input_data.servo_in_position.diff()!=0).cumsum()

but it gives output as in "second_servo_in_position" column, which is not what I wanted.

After that I would like to group and calculate mean using:

print("Mean=\n\n",input_data.groupby('second_servo_in_position').mean())

Upvotes: 11

Views: 2571

Answers (5)

Scott Boston
Scott Boston

Reputation: 153500

Use cumsum and mask:

df['E_output'] = df['servo_in_position'].diff().eq(1).cumsum()\ .mask(df['servo_in_position'] == 0, 0)

df['servo_in_position'].diff().fillna(df['servo_in_position']).eq(1).cumsum()\
   .mask(df['servo_in_position'] == 0, 0)

Output:

    servo_in_position  second_servo_in_position  Expected output  E_output
0                   0                         1                0         0
1                   0                         1                0         0
2                   1                         2                1         1
3                   0                         3                0         0
4                   1                         4                2         2
5                   1                         4                2         2
6                   0                         5                0         0
7                   0                         5                0         0
8                   1                         6                3         3
9                   0                         7                0         0
10                  1                         8                4         4
11                  0                         9                0         0
12                  1                        10                5         5
13                  1                        10                5         5
14                  1                        10                5         5
15                  0                        11                0         0
16                  0                        11                0         0
17                  0                        11                0         0
18                  1                        12                6         6
19                  1                        12                6         6
20                  0                        13                0         0
21                  0                        13                0         0
22                  0                        13                0         0

Update for first position equal to 1.

df['servo_in_position'].diff().fillna(df['servo_in_position']).eq(1).cumsum()\
   .mask(df['servo_in_position'] == 0, 0)

Upvotes: 10

piRSquared
piRSquared

Reputation: 294488

Fast with Numba

from numba import njit

@njit
def f(u):
    out = np.zeros(len(u), np.int64)
    a = out[0] = u[0]
    for i in range(1, len(u)):
        if u[i] == 1:
            if u[i - 1] == 0:
                a += 1
            out[i] = a
    return out

f(df.servo_in_position.to_numpy())

array([0, 0, 1, 0, 2, 2, 0, 0, 3, 0, 4, 0, 5, 5, 5, 0, 0, 0, 6, 6, 0, 0, 0])

Upvotes: 4

BENY
BENY

Reputation: 323326

That is cumsum and mul

df.servo_in_position.diff().eq(1).cumsum().mul(df.servo_in_position.eq(1),axis=0)

Upvotes: 6

user3483203
user3483203

Reputation: 51165

Using cumsum and arithmetic.


u = df['servo_in_position']

(u.eq(1) & u.shift().ne(1)).cumsum() * u

0     0
1     0
2     1
3     0
4     2
5     2
6     0
7     0
8     3
9     0
10    4
11    0
12    5
13    5
14    5
15    0
16    0
17    0
18    6
19    6
20    0
21    0
22    0
Name: servo_in_position, dtype: int64

Upvotes: 11

Quang Hoang
Quang Hoang

Reputation: 150785

Try np.where:

df['Expected_output'] = np.where(df.servo_in_position.eq(1),
                                 df.servo_in_position.diff().eq(1).cumsum(),
                                 0)

Upvotes: 7

Related Questions