0

Here below a dataframe.

df_strat = pd.DataFrame({'in_pos': [0, 0, 0, 1, 0, 0, -1, 0, 0, 0], 
                    'in': [0, 0, 0, 1, 0, 0, -1, 0, 0, 0]})

I need to update the 'in' column value, either when there is a '1' in the column 'in_pos' or when there is a '1' in the previous row of the 'in' column. Same when values are -1 and -1. And I would extend to any set of value.

So I used the following code only to test '1' values:

df_strat.loc[(df_strat['in_pos'].shift(1) == 1) | (df_strat['in'].shift(1) == 1), 'in'] = 1

I expect a recursive update using the loc method.

But instead, I get only a single row update as below.

enter image description here

I tried the following too :

conditions = [
(df_strat['in_pos'] == 1) | (df_strat['in'].shift(1).fillna(0) == 1),
(df_strat['in_pos'] == -1) | (df_strat['in'].shift(1).fillna(0) == -1),
(df_strat['in_pos'] == 0) | (df_strat['in'].shift(1).fillna(0) == 0)]

df_strat['in'] = np.select(conditions, [1, -1, 0], default=df_strat['in'])

but result is a below

enter image description here

Expected result is

df_expected = pd.DataFrame({'in_pos': [0, 0, 0, 1, 0, 0, -1,0,0,0], 
                    'in': [0, 0, 0, 1, 1, 1, -1, -1, -1,-1]})

Can anyone help ? thks.

8
  • 1
    Please provide a minimal reproducible example images are not reproducible Commented Jan 26, 2024 at 16:40
  • Ditto @mozway, and please provide what your expected output should look like formatted as a code block. Commented Jan 26, 2024 at 16:46
  • That said, given your example, it makes sense that only 1 value is updated. Commented Jan 26, 2024 at 16:54
  • @mozway you should help on cynicism forum Commented Jan 29, 2024 at 12:29
  • @gfxProg sorry? Have you tested the solution below? Did it work? Commented Jan 29, 2024 at 12:37

1 Answer 1

1

loc doesn't work "recursively". Given your code, it's expected that only one value is changed.

If you want to recursively select the column after a 1, this means that you want to select all columns after your condition is met once.

You can thus use a cummax on your boolean series:

cond = (df_strat['in_pos'].shift(1) == 1) | (df_strat['in'].shift(1) == 1)

# or
# cond = df_strat[['in', 'in_pos']].shift(1).eq(1).any(axis=1)

df.loc[cond.cummax(), 'in'] = 1

Example:

# input
df_strat = pd.DataFrame({'in': [0, 0, 0, 1, 0, 0, 0],
                         'in_pos': [0, 0, 0, 1, 0, 0, 0]})

# output
   in  in_pos
0   0       0
1   0       0
2   0       0
3   1       1
4   1       0
5   1       0
6   1       0
Sign up to request clarification or add additional context in comments.

2 Comments

thks. looks good but I get stuck when in_pos change value. Let me edit the question part.
@gfxProg don't forget to provide the matching expected output for your updated input

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.