1
resposta

Crosstab - % intra grupos

Na aula, conseguimos fazer uma tabela que mostra a porcentagem de cada sexo e cor no total da populacao:

percentual = pd.crosstab(dados.Sexo,
                         dados.Cor,
                         normalize = True) * 100
percentual.rename(index = sexo, inplace = True)
percentual.rename(columns = cor, inplace = True)
percentual

Output:

Cor    Indígena    Branca    Preta    Amarela    Parda
Sexo                    
Masculino    0.333160    28.883394    7.160333    0.305830    32.617126
Feminino    0.131442    12.520822    3.759761    0.152264    14.135867

Porém eu gostaria de ver a porcentagem intra categorias, ou seja, dado a tabela de frequência

frequencia = pd.crosstab(dados.Sexo,
                         dados.Cor)
frequencia.rename(index = sexo, inplace = True)
frequencia
Output:
Cor    0    2    4    6    8
Sexo                    
Masculino    256    22194    5502    235    25063
Feminino    101    9621    2889    117    10862

Eu queria ter uma tabela com a porcentagem de Masculino na Cor 0 (256/(256+101)=71%), o mesmo para Feminino na Cor 0, o mesmo para Cor 2, 4, etc.

1 resposta

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\CorIndígenaBrancaPretaAmarelaParda
Masculino0.48075141.67887310.3323940.44131547.066667
Feminino0.42814840.78423112.2467150.49597346.044934

Para validar basta realizar a soma normaliza_por_index.sum(axis='columns') cuja saída será:

Sexo
Masculino100.0
Feminino100.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\CorIndígenaBrancaPretaAmarelaParda
Masculino71.70868369.75954765.57025466.76136469.764788
Feminino28.29131730.24045334.42974633.23863630.235212

Para validar basta fazer a soma normaliza_por_coluna.sum() cuja saída será:

Cor
Indígena100.0
Branca100.0
Preta100.0
Amarela100.0
Parda100.0
dtype: float64

Espero ter ajudado, abraço e bons estudos!