Boa tarde, Marcelo, tudo bem com você?
Antes de mais nada, desculpe pela demora para responder.
Muito boa a sua pergunta, em outras situações poderemos ter que apresentar nossos dados de outra forma. Para aprendermos a fazer isso, vamos pensar o que significa o parâmetro normalize da função pandas.crosstab()? Neste caso, significa que os dados serão normalizados dividindo todos os valores pela soma dos valores.
Legal, como você percebeu quando utilizamos o parâmetro normalize = True a normalização está sendo feita em relação a todos os dados. Para validar basta realizar a soma entre todos os valores do DataFrame percentual , linhas + colunas. A forma mais rápida de fazermos isso é percentual.sum().sum(), onde o primeiro .sum() retorna a soma das linhas e o segundo pega o retorno anterior e soma com a soma das colunas.
Como está em porcentagem (%), a saída será:
100.00
Tudo bem, mas como fazemos normalização com outras relações no crosstab? Será que o normalize pode receber outros valores diferentes de True ou False? Olha só que interessante, quando olhamos na documentação pandas.crosstab descobrimos que ele aceita também os seguintes valores: 'all', 'index', 'columns', ou {0,1}.
Para os casos de normalize = True ou normalize = 'all': É a normalização que vimos acima, em relação a todos.
Para os casos de normalize = 0 ou normalize = 'index': Normalizará em cada linha.
Para os casos de normalize = 1 ou normalize = 'columns': Normalizará em cada coluna.
Por fim, vamos exemplificar os dois últimos casos com os códigos a seguir. Primeiro em relação a linha:
normaliza_por_index = pd.crosstab(dados.Sexo,
dados.Cor,
normalize = 'index') * 100
normaliza_por_index.rename(index = sexo, inplace = True)
normaliza_por_index.rename(columns = cor, inplace = True)
normaliza_por_index
Saída:
| Sexo\Cor | Indígena | Branca | Preta | Amarela | Parda |
|---|
| Masculino | 0.480751 | 41.678873 | 10.332394 | 0.441315 | 47.066667 |
| Feminino | 0.428148 | 40.784231 | 12.246715 | 0.495973 | 46.044934 |
Para validar basta realizar a soma normaliza_por_index.sum(axis='columns') cuja saída será:
| Sexo | |
|---|
| Masculino | 100.0 |
| Feminino | 100.0 |
| dtype: float64 | |
Vamos fazer o segundo em relação às colunas:
normaliza_por_coluna = pd.crosstab(dados.Sexo,
dados.Cor,
normalize = 'columns') * 100
normaliza_por_coluna.rename(index = sexo, inplace = True)
normaliza_por_coluna.rename(columns = cor, inplace = True)
normaliza_por_coluna
Saída:
| Sexo\Cor | Indígena | Branca | Preta | Amarela | Parda |
|---|
| Masculino | 71.708683 | 69.759547 | 65.570254 | 66.761364 | 69.764788 |
| Feminino | 28.291317 | 30.240453 | 34.429746 | 33.238636 | 30.235212 |
Para validar basta fazer a soma normaliza_por_coluna.sum() cuja saída será:
| Cor | |
|---|
| Indígena | 100.0 |
| Branca | 100.0 |
| Preta | 100.0 |
| Amarela | 100.0 |
| Parda | 100.0 |
| dtype: float64 | |
Espero ter ajudado, abraço e bons estudos!