Одна идея - использовать DataFrame.loc
с условием и указать оба столбца в списке - так можно назначить список [5,7]
:
df.loc[df['Age'] == 9, ['Score 1','Score 2']] = [5,7]
df.loc[df['Age'] == 10, ['Score 1','Score 2']] = [10,12]
print (df)
Age Score 1 Score 2 AA
0 9 5.0 7.0 144
1 10 10.0 12.0 133
2 9 5.0 7.0 100
3 8 14.0 1.5 110
4 14 14.0 1.2 97
Другая - использовать numpy.select
с широковещательной передачей, поскольку работа с обоими столбцами:
m1 = df['Age'].eq(9).values[:, None]
m2 = df['Age'].eq(10).values[:, None]
v1 = [5,7]
v2 = [10, 12]
df[['Score 1','Score 2']] = np.select([m1, m2], [v1, v2], default = df[['Score 1','Score 2']])
print (df)
Age Score 1 Score 2 AA
0 9 5.0 7.0 144
1 10 10.0 12.0 133
2 9 5.0 7.0 100
3 8 14.0 1.5 110
4 14 14.0 1.2 97
Решение с использованием лямбды возможно, но очень медленно:
s = pd.Series([5, 7], index=['Score 1','Score 2'])
f = lambda x: s if x['Age'] == 9 else x[['Score 1', 'Score 2']]
df[['Score 1','Score 2']] = df.apply(f, axis=1)
print (df)
Age Score 1 Score 2 AA
0 9 5.0 7.0 144
1 10 12.0 3.1 133
2 9 5.0 7.0 100
3 8 14.0 1.5 110
4 14 14.0 1.2 97
Производительность :
#5k rows
df = pd.concat([df] * 1000, ignore_index=True)
In [113]: %timeit df.loc[df['Age'] == 9, ['Score 1','Score 2']] = [5,7]
2.35 ms ± 28.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [114]: %timeit df[['Score 1','Score 2']] = df.apply(lambda x: pd.Series([5, 7], index=['Score 1','Score 2']) if x['Age'] == 9 else x[['Score 1', 'Score 2']], axis=1)
2.88 s ± 138 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Производительность первых 2 решений для большего количества строк:
#50k rows
df = pd.concat([df] * 10000, ignore_index=True)
In [120]: %%timeit
...: df.loc[df['Age'] == 9, ['Score 1','Score 2']] = [5,7]
...: df.loc[df['Age'] == 10, ['Score 1','Score 2']] = [10,12]
...:
6.33 ms ± 59.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [121]: %%timeit
...: df[['Score 1','Score 2']] = np.select([df['Age'].eq(9).values[:, None], df['Age'].eq(10).values[:, None]], [[5,7], [10, 12]], df[['Score 1','Score 2']])
...:
19.1 ms ± 139 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)