Если pre
всегда первый для групп и значения в выходных данных должны повторяться:
df['diff'] = df.groupby('IDs')['Response'].transform(lambda x: (x.iat[0] - x).min())
Только для первого значения для групп возможно заменить значения пустыми строками, но получить смешанные значения - числовые сстроки, поэтому следующая обработка должна быть проблемой:
df['diff'] = df['diff'].mask(df['diff'].duplicated(), '')
РЕДАКТИРОВАТЬ:
df = pd.DataFrame({
'Response':[2,5,0.4,2,1,4],
'Time':[7,'pre',9,4,2,'pre'],
'IDs':list('aaabbb')
})
#print (df)
d = df[df.Time=="pre"].set_index('IDs')['Response'].to_dict()
print (d)
{'a': 5.0, 'b': 4.0}
df['diff'] = df.groupby('IDs')['Response'].transform(lambda x: d[x.name] - x.min())
print (df)
Response Time IDs diff
0 2.0 7 a 4.6
1 5.0 pre a 4.6
2 0.4 9 a 4.6
3 2.0 4 b 3.0
4 1.0 2 b 3.0
5 4.0 pre b 3.0