Из датафрейма вычесть столбец

Есть датафрейм

df = pd.DataFrame({
    'a':(1,2,3,2.003),
    'b':(2,2,6,1.993),
    'f':(2.5,2,6,2.0),
    'flag':(False,False,False,False),
})
df

       a      b    f   flag
0  1.000  2.000  2.5  False
1  2.000  2.000  2.0  False
2  3.000  6.000  6.0  False
3  2.003  1.993  2.0  False

С ним можно так.

df[['a','b']]
       a      b
0  1.000  2.000
1  2.000  2.000
2  3.000  6.000
3  2.003  1.993

И так.

df[['a','b']] - 2

       a      b
0 -1.000  0.000
1  0.000  0.000
2  1.000  4.000
3  0.003 -0.007

Но вычитание столбца неожиданно пугает

df[['a','b']] - df.f
Out[31]: 
    a   b   0   1   2   3
0 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN

Я ожидал два столбца, из которых поэлементно вычли элементы третьего солбца. Что не так?


Ответы (2 шт):

Автор решения: Guamokolatokint

Оси укажите

df[['a','b']].sub(df.f,axis=0)

a   b
0   -1.500  -0.500
1   0.000   0.000
2   -3.000  0.000
3   0.003   -0.007
→ Ссылка
Автор решения: Vasyl Kolomiets

Ну после вашего ответа я нашел вариант нагляднее - на мой вкус, конечно. Но мне умолчание Pandas кажется нелогичным. Нужно транспонирование до и после:

(df[['a','b']].T - df.f).T

Дает тот же результат, что и ваш вариант с использованием .sub(). Интересно, чем вызвано такое страное желание отнимать не столбцами, а по строке? В чем здравый смысл, который от меня ускользает?
Ведь Pandas это все же по столбцам в первую очередь, не правда ли?

К слову, вариант прямого вызова метода .sub() несколько, но непринципиально быстрее: введите сюда описание изображения

Однако на больших размерностях, как указал @Guamokolatokint, двойное транспонирование оказывается накладным по времени.

→ Ссылка