1

I have 2 columns on whose value I want to update the third column for only 1 row.

I have-

df = pd.DataFrame({'A':[1,1,2,3,4,4],
                   'B':[2,2,4,3,2,1],
                   'C':[0] * 6})
print (df)
   A  B  C
0  1  2  0
1  1  2  0
2  2  4  0
3  3  3  0
4  4  2  0
5  4  1  0

If A= 1 and B=2 then only 1st row has C=1 like this -

print (df)
   A  B  C
0  1  2  1
1  1  2  0
2  2  4  0
3  3  3  0
4  4  2  0
5  4  1  0

Right now I have used

df.loc[(df['A']==1) & (df['B']==2)].iloc[[0]].loc['C'] = 1

but it doesn't change the dataframe.

Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
user2828360
  • 87
  • 1
  • 13

2 Answers2

3

Solution if match always at least one row:

Create boolean mask and set to first True index value by idxmax:

mask = (df['A']==1) & (df['B']==2)

df.loc[mask.idxmax(), 'C'] = 1

But if no value matched idxmax return first False value, so added if-else:

mask = (df['A']==1) & (df['B']==2)

idx = mask.idxmax() if mask.any() else np.repeat(False, len(df))
df.loc[idx, 'C'] = 1
print (df)
   A  B  C
0  1  2  1
1  1  2  0
2  2  4  0
3  3  3  0
4  4  2  0
5  4  1  0

mask = (df['A']==10) & (df['B']==20)

idx = mask.idxmax() if mask.any() else np.repeat(False, len(df))
df.loc[idx, 'C'] = 1
print (df)
   A  B  C
0  1  2  0
1  1  2  0
2  2  4  0
3  3  3  0
4  4  2  0
5  4  1  0
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
0

Using pd.Series.cumsum to ensure only the first matching criteria is satisfied:

mask = df['A'].eq(1) & df['B'].eq(2)
df.loc[mask & mask.cumsum().eq(1), 'C'] = 1

print(df)

   A  B  C
0  1  2  1
1  1  2  0
2  2  4  0
3  3  3  0
4  4  2  0
5  4  1  0

If performance is a concern, see Efficiently return the index of the first value satisfying condition in array.

jpp
  • 159,742
  • 34
  • 281
  • 339