Pandas Dataframe replace Nan from a row when a column value matches

Use forward and back filling missing values per groups with lambda function in columns specified in list with DataFrame.groupby - is necessary for each combination same values per groups:

cols = ['school','city']
df[cols] = df.groupby(['class','section'])[cols].apply(lambda x: x.ffill().bfill())
print (df)
  class section  sub  marks school   city
0     I       A  Eng     80  jghss  salem
1     I       A  Mat     90  jghss  salem
2     I       A  Eng     50  jghss  salem
3   III       A  Eng     80  gphss  salem
4   III       A  Mat     45  gphss  salem
5   III       A  Eng     40  gphss  salem
6   III       A  Eng     20  gphss  salem
7   III       A  Mat     55  gphss  salem