dtype: integer, but loc returns float

You get back a float because each row contains a mix of float and int types. Upon selecting a row index with loc, integers are cast to floats:

>>> df.loc[4]
year          1979.000000
firms       390352.000000
age              1.000000
survival         0.774522
Name: 4, dtype: float64

So choosing the age entry here with df.loc[4, 'age'] would yield 1.0.

To get around this and return an integer, you could use loc to select from just the age column and not the whole DataFrame:

>>> df['age'].loc[4]
1

This was a bug in pandas up through version 0.19. It seems to have been fixed in version 0.20. cf. https://github.com/pandas-dev/pandas/issues/11617