Это немного повсеместно и жестко закодировано, но оно должно работать. Я назвал NaN столбцы ['A', 'C', 'D']
data hora machine A B C D
0 2017-08-18 09:22:33 22162 NaN 65.9 NaN NaN
1 2017-10-03 11:08:26 22162 NaN 60.5 NaN NaN
2 2018-02-17 01:45:24 22162 NaN 69.7 NaN NaN
3 2018-02-17 01:45:55 74034 NaN 67.5 NaN NaN
4 2018-02-17 01:46:29 74034 NaN 65.4 NaN NaN
5 2018-02-17 01:47:20 74034 NaN 63.3 NaN NaN
6 2018-02-17 01:48:35 74034 NaN 61.3 NaN NaN
7 2018-02-17 01:49:08 17448 NaN 63.4 NaN NaN
8 2018-02-17 01:49:31 17448 NaN 65.5 NaN NaN
9 2018-02-17 01:49:55 17448 NaN 67.6 NaN NaN
columns = ['A', 'C', 'D']
for clm in columns:
df[clm] = df[clm].fillna(df.machine.map(df.groupby('machine')['B'].mean().to_dict()))
Результаты в
data hora machine A B C D
0 2017-08-18 09:22:33 22162 65.366667 65.9 65.366667 65.366667
1 2017-10-03 11:08:26 22162 65.366667 60.5 65.366667 65.366667
2 2018-02-17 01:45:24 22162 65.366667 69.7 65.366667 65.366667
3 2018-02-17 01:45:55 74034 64.375000 67.5 64.375000 64.375000
4 2018-02-17 01:46:29 74034 64.375000 65.4 64.375000 64.375000
5 2018-02-17 01:47:20 74034 64.375000 63.3 64.375000 64.375000
6 2018-02-17 01:48:35 74034 64.375000 61.3 64.375000 64.375000
7 2018-02-17 01:49:08 17448 65.500000 63.4 65.500000 65.500000
8 2018-02-17 01:49:31 17448 65.500000 65.5 65.500000 65.500000
9 2018-02-17 01:49:55 17448 65.500000 67.6 65.500000 65.500000
Вероятно, не лучшим способом, но выполняет работу.