8

I'm trying to conditionally update multiple rows in my panda dataframe. Here's my data:

df = pd.DataFrame([[1,1,1], [2,2,2], [3,3,3]], columns=list('ABC'))

I can do the update I want in two steps:

df.loc[df['A'] == 1, 'B'] = df['C'] +10
df.loc[df['A'] == 1, 'A'] = df['C'] +11

Or I can update to constant values in one step:

df.loc[df['A'] == 1, ['A', 'B']] = [11, 12]

But I can't update multiple columns from other columns in a single step:

df.loc[df['A'] == 1, ['A', 'B']] = [df['C'] + 10, df['C'] + 11]
...
ValueError: shape mismatch: value array of shape (2,3) could not be broadcast to indexing result of shape (1,2)

Any ideas how I can do this?


Edit: Thanks @EdChum for the simple solution for the simple case - have updated the question to demonstrate a more complex reality.

Matthew
  • 10,361
  • 5
  • 42
  • 54

3 Answers3

11

So looking at this question a couple years later I see the error, to coerce the returned result so it assigns correctly you need to access the scalar values and use these to assign so they align as desired:

In [22]:
df.loc[df['A'] == 1, ['A', 'B']] = df['C'].values[0] + 10,df['C'].values[0] + 11
df

Out[22]:
    A   B  C
0  11  12  1
1   2   2  2
2   3   3  3
EdChum
  • 376,765
  • 198
  • 813
  • 562
5

I'm nor sure whether it's the best way to achieve that, but it works:

In [284]: df.loc[df['A'] == 1, ['A', 'B']] = pd.DataFrame({'A':df.C + 10, 'B':df.C + 11}, index=df.index)

In [285]: df
Out[285]:
    A   B  C
0  11  12  1
1   2   2  2
2   3   3  3
MaxU - stand with Ukraine
  • 205,989
  • 36
  • 386
  • 419
0

This code might help someone trying to achieve a similar objective. It updates the status and history columns with the values 'ERROR' and 'MESSAGE' respectively for rows where the values in the title column match the regex.

df.loc[
    df['title'].str.contains('pattern', regex=True), ['status', 'history']
] = ['ERROR', 'MESSAGE']
Eric O.
  • 474
  • 4
  • 23