Boa tarde,
1) Não entendi a explicação do professor quanto ao código usando o ~ em dados = dados[~selecao]. Está claro que o ~ inverte a lógica boolena de seleção, o que não entendi é como esse comando é capaz de eliminar os registros. No exemplo imediatamente anterior dados.dropna(subset = ['Valor'], inplace=True), o método  .dropna deixa claro que há a eliminação dos registros nulos. 
Poderia explicar melhor o uso do ~ no sentido de eliminar registros?
2) Apenas uma observação: acredito que a lógica de campos nulos em IPTU não seja de preenche-los com ZERO e sim eliminar essas linhas, já que não existe imóvel sem IPTU. Ou seja, nesse caso, o dataframe está incorreto e seria preciso eliminar os registros, assim como foi feito para 'Apartamento' com 'Condomínio' nulo.
Obrigado,
 
             
            