Assign a value to the first row of a sub-dataframe

Viewed 206

I have a Pandas dataframe that looks like this:

df = pd.DataFrame({'gp_id': [1, 2, 1, 2], 'A': [1, 2, 3, 4]})

   gp_id  A
0      1  1
1      2  2
2      1  3
3      2  4

I want to assign the value -1 to the first row of the group with the id 2 (gp_id = 2), to get the following output:

   gp_id  A
0      1  1
1      2 -1
2      1  3
3      2  4

To do this, I've tried the following code:

df[df.gp_id == 2].A.iloc[0] = -1

But this doesn't do anything as I'm assigning a value in the sub-dataframe df[df.gp_id == 2] and I'm not modifying the original dataframe df.

Is there an easy way to solve this problem?

2 Answers

You could do:

df.loc[(df.gp_id == 2).argmax(), 'A'] = -1

as pd.Series.argmax returns the first max.

If you are not sure that the value is present in the dataframe, you could do:

cond = (df.gp_id == 2)
if cond.sum():
    df.loc[cond.argmax(), 'A'] = -1

General solution if possible mask return no rows is chain another mask by cumulative sum of mask by & for bitwise AND and set values by DataFrame.loc:

m = df.gp_id == 2
df.loc[m & (m.cumsum() == 1), 'A'] = -1

Working well if no match - no assign, no error, no incorrect assignment:

m = df.gp_id == 7
df.loc[m & (m.cumsum() == 1), 'A'] = -1

Solution if always match mask at least one row is:

idx = df[df.gp_id == 2].index[0]

df.loc[idx, 'A'] = -1
print (df)
   gp_id  A
0      1  1
1      2 -1
2      1  3
3      2  4

If no match, solution raise error, no incorrect assignment.

Related