dataframe is not updated while using loc function

75 Views Asked by At

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.

1

There are 1 best solutions below

2
mozway On

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