Olá Rafaela, tudo bem? Espero que sim!
Inicialmente foi criado um DataFrame vazio, que se chama dados_new para armazenar as informações que eram desejadas.
As informações que queríamos obter eram os dados que estão acima do limite inferior e abaixo do limite superior. Dessa forma eliminamos os outliers dos dados.
Acontece que o limite inferior e superior vai depender do tipo de imóvel, cada tipo tem valores que variam de maneiras diferentes. Portanto, ao realizar o for que percorre cada um dos tipos, conseguimos primeiro selecionar somente os registros daquele tipo fazendo eh_tipo = dados['Tipo'] == tipo
. Conseguimos também selecionar os valores que estão dentro desse intervalo criado para cada tipo, fazendo eh_dentro_limite = (dados['Valor'] >= limite_inferior[tipo]) & (dados['Valor'] <= limite_superior[tipo])
.
A seleção será feita quando satisfazer essas duas condições simultaneamente, ou seja, for de determinado tipo e tiver os valores dentro do intervalo que depende daquele tipo. Ao fim do for, usamos o pd.concat() para colocar essas informações no DataFrame que começou vazio. A cada tipo, ou seja, a cada execução do for acrescentaremos novas informações referentes ao tipo em que o for está atualmente.
Primeiro o tipo será 'Apartamento', portanto a primeira execução do for será substituir todos os valores tipo por 'Apartamento':
eh_tipo = dados['Tipo'] == 'Apartamento'
eh_dentro_limite = (dados['Valor'] >= limite_inferior['Apartamento']) & (dados['Valor'] <= limite_superior['Apartamento'])
selecao = eh_tipo & eh_dentro_limite
dados_selecao = dados[selecao]
dados_new = pd.concat([dados_new, dados_selecao])
Colocamos no DataFrame os dados que são do tipo 'Apartamento' e estão dentro dos limites inferior e superior para o tipo 'Apartamento'. A partir de agora o DataFrame dados_new não está mais vazio, pois tem os dados referentes aos apartamentos. Na segunda execução do for, o tipo será 'Casa', portanto será executado:
eh_tipo = dados['Tipo'] == 'Casa'
eh_dentro_limite = (dados['Valor'] >= limite_inferior['Casa']) & (dados['Valor'] <= limite_superior['Casa'])
selecao = eh_tipo & eh_dentro_limite
dados_selecao = dados[selecao]
dados_new = pd.concat([dados_new, dados_selecao])
Dessa forma o dados_new, que possuía os dados de 'Apartamento', receberá agora os dados do tipo 'Casa'.
O código seguirá da mesma maneira até que o for termine, ou seja, até que seja executado para todos os tipos.
Espero que tenha tirado sua dúvida.
Estou à disposição. Bons estudos!