As Nações Unidas fornecem o conjunto de dados Word Population Prospects (WPP) sobre distribuição geográfica e etária da humanidade como arquivos XLSX baixáveis.
Ler estes arquivos em Python é bastante fácil. Primeiro temos que descobrir quantas linhas pular. Para o conjunto de dados WPP 2019 este valor é 16 já que a linha 17 contém todos os cabeçalhos das colunas. O número de linhas a pular pode ser diferente dependendo do conjunto de dados. Estamos usando WPP2019_POP_F07_1_POPULATION_BY_AGE_BOTH_SEXES.xlsx neste exemplo.
Podemos usar a função read_excel() do Pandas para importar o conjunto de dados em Python:
import pandas as pd
df = pd.read_excel("WPP2019_INT_F03_1_POPULATION_BY_AGE_ANNUAL_BOTH_SEXES.xlsx", skiprows=16, na_values=["..."])Isso levará alguns segundos até que o grande conjunto de dados tenha sido processado. Agora podemos verificar se skiprows=16 é o valor correto. Está correto se pandas reconheceu os nomes das colunas corretamente:
>>> df.columns
Index(['Index', 'Variant', 'Region, subregion, country or area *', 'Notes',
'Country code', 'Type', 'Parent code', 'Reference date (as of 1 July)',
'0-4', '5-9', '10-14', '15-19', '20-24', '25-29', '30-34', '35-39',
'40-44', '45-49', '50-54', '55-59', '60-64', '65-69', '70-74', '75-79',
'80-84', '85-89', '90-94', '95-99', '100+'],
dtype='object')Agora vamos filtrar por um país:
russia = df[df["Region, subregion, country or area *"] == 'Russian Federation']Isso nos mostrará os dados de população para múltiplos anos em intervalos de 5 anos de 1950 a 2020. Agora vamos filtrar pelo ano mais recente:
russia.loc[russia["Reference date (as of 1 July)"].idxmax()]Isso nos mostrará um único conjunto de dados:
Index 3255
Variant Estimates
Region, subregion, country or area * Russian Federation
Notes NaN
Country code 643
Type Country/Area
Parent code 923
Reference date (as of 1 July) 2020
0-4 9271.69
5-9 9350.92
10-14 8174.26
15-19 7081.77
20-24 6614.7
25-29 8993.09
30-34 12543.8
35-39 11924.7
40-44 10604.6
45-49 9770.68
50-54 8479.65
55-59 10418
60-64 10073.6
65-69 8427.75
70-74 5390.38
75-79 3159.34
80-84 3485.78
85-89 1389.64
90-94 668.338
95-99 102.243
100+ 9.407
Name: 3254, dtype: objectComo podemos plotar esses dados? Primeiro, precisamos selecionar todas as colunas que contêm dados de idade. Faremos isso inserindo manualmente o nome da primeira coluna (0-4) no código a seguir e assumindo que não há colunas após a última coluna de idade:
>>> df.columns[df.columns.get_loc("0-4"):]
Index(['0-4', '5-9', '10-14', '15-19', '20-24', '25-29', '30-34', '35-39',
'40-44', '45-49', '50-54', '55-59', '60-64', '65-69', '70-74', '75-79',
'80-84', '85-89', '90-94', '95-99', '100+'],
dtype='object')Agora vamos selecionar essas colunas do conjunto de dados russia:
most_recent_russia = russia.loc[russia["Reference date (as of 1 July)"].idxmax()]
age_columns = df.columns[df.columns.get_loc("0-4"):]
russian_age_data = most_recent_russia[age_columns]Vamos dar uma olhada no conjunto de dados:
>>> russian_age_data
0-4 9271.69
5-9 9350.92
10-14 8174.26
15-19 7081.77
20-24 6614.7
25-29 8993.09
30-34 12543.8
35-39 11924.7
40-44 10604.6
45-49 9770.68
50-54 8479.65
55-59 10418
60-64 10073.6
65-69 8427.75
70-74 5390.38
75-79 3159.34
80-84 3485.78
85-89 1389.64
90-94 668.338
95-99 102.243
100+ 9.407Isso parece utilizável, note entretanto que os valores estão em milhares, i.e. temos que multiplicar os valores por 1000 para obter as estimativas reais da população. Vamos plotar:
from matplotlib import pyplot as plt
plt.style.use("ggplot")
plt.title("Age composition of the Russian population (2020)")
plt.ylabel("People in age group [Millions]")
plt.xlabel("Age group")
plt.gcf().set_size_inches(15,5)
# Data is given in thousands => divide by 1000 to obtain millions
plt.plot(russian_age_data.index, russian_age_data.as_matrix() / 1000., lw=3)O gráfico finalizado se parecerá com isto:
Aqui está nosso script finalizado:
#!/usr/bin/env python3
import pandas as pd
df = pd.read_excel("WPP2019_POP_F07_1_POPULATION_BY_AGE_BOTH_SEXES.xlsx", skiprows=16)
# Filter only russia
russia = df[df["Region, subregion, country or area *"] == 'Russian Federation']
# Filter only most recent estimate (1 row)
most_recent_russia = russia.loc[russia["Reference date (as of 1 July)"].idxmax()]
# Retain only value columns
age_columns = df.columns[df.columns.get_loc("0-4"):]
russian_age_data = most_recent_russia[age_columns]
# Plot!
from matplotlib import pyplot as plt
plt.style.use("ggplot")
plt.title("Age composition of the Russian population (2020)")
plt.ylabel("People in age group [Millions]")
plt.xlabel("Age group")
plt.gcf().set_size_inches(15,5)
# Data is given in thousands => divide by 1000 to obtain millions
plt.plot(russian_age_data.index, russian_age_data.as_matrix() / 1000., lw=3)
# Export as SVG
plt.savefig("russian-demographics.svg")