Análise de dados no Python: Diárias e passagens gaúchas
Olá! Este é um exercício em análise e exploração de dados em Python. Aqui, vamos aplicar as funcionalidades do pacote pandas
em um arquivo que contém o histório de concessões de diárias e passagens a pessoas físicas no estado do Rio Grande do Sul, em 2017. Os dados contém informações sobre órgãos responsáveis, origens e destinos de viagens, pessoas beneficiadas e valores pagos em R$ correntes de 2017.
Vamos começar carregando os pacotes necessários:
%matplotlib inline
import pandas as pd
import numpy as np
import seaborn as sns
sns.set()
Agora, vamos fazer o download dos dados do Portal da Transparência do RS. Os dados vêm em formato *.csv
, com o separador ponto-e-vírgula:
#!curl http://antigo.transparencia.rs.gov.br/ARQUIVOS/Diarias-RS-2017.zip
#!unzip Diarias-RS-2017.zip
df = pd.read_csv('Diarias-RS-2017.csv', sep=';', encoding='windows-1252')
Agora, vamos ver como os dados foram importados:
df.head()
Exercicio | Mes | Poder | Cod_Setor_Gov | Setor | Cod_orgao | Orgao | Cod_UO | UO | Cod_Credor | ... | DataInicio | DataFim | Quantidade | QuantidadeMeia | Destino | Tipo | Motivo | Valor | Origem | Empenho | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2017 | 1 | PODER EXECUTIVO | 19 | DIRETA | 20 | SECRETARIA DA SAUDE | 2095 | FUNDO ESTADUAL DE SAUDE | 6998 | ... | 14/12/2016 | 14/12/2016 | 0 | 1 | BUTIA | DIARIA COMUM VENCID-CIVIL | INSPECOES/AUDITORIAS | 61,50 | CHARQUEADAS | 17000146930 |
1 | 2017 | 1 | PODER EXECUTIVO | 19 | DIRETA | 20 | SECRETARIA DA SAUDE | 2095 | FUNDO ESTADUAL DE SAUDE | 6998 | ... | 07/12/2016 | 07/12/2016 | 0 | 1 | CAMAQUA | DIARIA COMUM VENCID-CIVIL | INSPECOES/AUDITORIAS | 61,50 | CHARQUEADAS | 17000146996 |
2 | 2017 | 1 | PODER EXECUTIVO | 19 | DIRETA | 20 | SECRETARIA DA SAUDE | 2095 | FUNDO ESTADUAL DE SAUDE | 6998 | ... | 28/12/2016 | 28/12/2016 | 0 | 1 | SAO JERONIMO | DIARIA COMUM VENCID-CIVIL | INSPECOES/AUDITORIAS | 61,50 | CHARQUEADAS | 17000157622 |
3 | 2017 | 1 | PODER EXECUTIVO | 19 | DIRETA | 20 | SECRETARIA DA SAUDE | 2095 | FUNDO ESTADUAL DE SAUDE | 6998 | ... | 18/01/2017 | 18/01/2017 | 0 | 1 | BARRA DO RIBEIRO | DIARIA COMUM VENCID-CIVIL | REUNIOES TECNICAS | 61,50 | CHARQUEADAS | 17000303577 |
4 | 2017 | 1 | PODER EXECUTIVO | 19 | DIRETA | 15 | SECRETARIA DA AGRICULTURA, PECUARIA E IRRIGACAO | 1501 | GABINETE E ORGAOS CENTRAIS | 8745 | ... | 25/10/2016 | 25/10/2016 | 0 | 1 | SANTA MARIA | DIARIA COMUM VENCID-CIVIL | REUNIOES ADMINISTRATIVAS | 61,50 | JARI | 16006041272 |
5 rows × 21 columns
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 268874 entries, 0 to 268873
Data columns (total 21 columns):
Exercicio 268874 non-null int64
Mes 268874 non-null int64
Poder 268874 non-null object
Cod_Setor_Gov 268874 non-null int64
Setor 268874 non-null object
Cod_orgao 268874 non-null int64
Orgao 268874 non-null object
Cod_UO 268874 non-null int64
UO 268874 non-null object
Cod_Credor 268874 non-null int64
Favorecido 268874 non-null object
DataInicio 262676 non-null object
DataFim 262676 non-null object
Quantidade 268874 non-null int64
QuantidadeMeia 268874 non-null int64
Destino 268530 non-null object
Tipo 268874 non-null object
Motivo 268874 non-null object
Valor 268874 non-null object
Origem 268874 non-null object
Empenho 268874 non-null int64
dtypes: int64(9), object(12)
memory usage: 43.1+ MB
A coluna com os valores dos empenhos foram interpretadas como texto, por causa da vírgula como separador decimal. Vamos corrigir:
df['Valor'] = df.Valor.str.replace(pat=',', repl='.')
df['Valor'] = df.Valor.astype(float)
Agora, vamos ocultar o nome completo dos beneficiados, para fins didáticos:
df['Favorecido2'] = df.Favorecido.str.split()
df['Favorecido2'] = df.Favorecido2.apply(lambda x: x[-1])
A partir daqui já podemos fazer algumas análises, com o uso da função groupby
do pacote pandas
. Com ela é possível obter estatísticas agregadas por grupos. Vamos descobrir quais servidores receberam os maiores valores em diárias e passagens:
df.groupby(['Cod_Credor','Favorecido2'])['Valor'].sum().nlargest(10)
Cod_Credor Favorecido2
21594481 PAESE 60088.33
21544697 CAYE 51664.02
21570051 SILVA 51336.00
10161040 RAMOS 51110.52
34346732 GARCIA 49799.23
18567100 MAINARDI 48719.62
6051006 PEIXOTO 48598.50
23170433 BORBA 48479.53
33839395 SILVA 47125.32
40092020 GOMES 45246.32
Name: Valor, dtype: float64
Ou então, quais os maiores fluxos entre unidades orçamentárias e órgãos que concedem os benefícios:
df.groupby(['UO','Orgao'])['Valor'].sum().nlargest(10).round()
UO Orgao
BRIGADA MILITAR SECRETARIA DA SEGURANCA PUBLICA 28326579.0
DEPARTAMENTO AUTONOMO DE ESTRADAS DE RODAGEM DEPARTAMENTO AUTONOMO DE ESTRADAS DE RODAGEM 13128503.0
SUPERINTENDENCIA DOS SERVICOS PENITENCIARIOS SECRETARIA DA SEGURANCA PUBLICA 7612260.0
CORPO DE BOMBEIROS MILITAR SECRETARIA DA SEGURANCA PUBLICA 4765460.0
DEPARTAMENTO ESTADUAL DE TRANSITO DEPARTAMENTO ESTADUAL DE TRANSITO 3887284.0
POLICIA CIVIL SECRETARIA DA SEGURANCA PUBLICA 3766606.0
ASSEMBLEIA LEGISLATIVA ASSEMBLEIA LEGISLATIVA 3193683.0
GABINETE E ORGAOS CENTRAIS SECRETARIA DA AGRICULTURA, PECUARIA E IRRIGACAO 3156240.0
PROCURADORIA-GERAL DE JUSTICA MINISTERIO PUBLICO 3103149.0
GABINETE E ORGAOS CENTRAIS SECRETARIA DA SEGURANCA PUBLICA 3085936.0
Name: Valor, dtype: float64
Quais são as viagens mais frequentes?
df.groupby(['Origem','Destino'])['Quantidade'].sum().nlargest(20)
Origem Destino
PORTO ALEGRE ALEGRETE 67886
ANTONIO PRADO 60853
AGUDO 45462
TRAMANDAI 21107
PORTO ALEGRE 18483
PASSO FUNDO PORTO ALEGRE 12799
PORTO ALEGRE CAPAO DA CANOA 12470
SANTA MARIA PORTO ALEGRE 11074
PORTO ALEGRE TORRES 7322
CIDREIRA 6514
OSORIO 5372
CHARQUEADAS 4953
SANTO ANGELO PORTO ALEGRE 4769
PELOTAS PORTO ALEGRE 4201
SANTA MARIA CAPAO DA CANOA 3617
PORTO ALEGRE CAXIAS DO SUL 3492
CACHOEIRA DO SUL PORTO ALEGRE 3478
PELOTAS RIO GRANDE 3272
PORTO ALEGRE PASSO FUNDO 2959
SANTA MARIA NOVO HAMBURGO 2881
Name: Quantidade, dtype: int64
Quais viagens representam os maiores valores gastos em 2017? Elas coincidem com os valores mostrados acima?
df.groupby(['Origem','Destino'])['Valor'].sum().nlargest(20)
Origem Destino
PORTO ALEGRE TRAMANDAI 2721824.31
PASSO FUNDO PORTO ALEGRE 1985408.88
SANTA MARIA PORTO ALEGRE 1796298.20
PORTO ALEGRE CAPAO DA CANOA 1627620.17
ALEGRETE 1252773.67
ANTONIO PRADO 1139786.58
TORRES 975725.28
N/D N/D 946698.35
PORTO ALEGRE DF 925746.10
CIDREIRA 819431.60
AGUDO 801317.16
OSORIO 793824.58
SANTO ANGELO PORTO ALEGRE 746511.73
PELOTAS PORTO ALEGRE 720271.00
PORTO ALEGRE CAXIAS DO SUL 635554.39
EXTERIOR 593282.20
SP 579742.97
CACHOEIRA DO SUL PORTO ALEGRE 554328.30
CHARQUEADAS PORTO ALEGRE 550244.71
PORTO ALEGRE CHARQUEADAS 548256.21
Name: Valor, dtype: float64
Cada diária/passagem deve ter registrada um motivo associado:
df.groupby('Motivo')['Valor'].sum().nlargest(20).round()
Motivo
OPERACAO LITORAL 25177625.0
SERVICOS TECNICOS 9045394.0
REFORCOS A OUTRA OPM 8213390.0
OPERACAO CANARINHO 3538243.0
RESSARC SERVIDOR BPR DAER 3413129.0
PARTICIP.EM TREIN./CURSOS 2990233.0
SERV.CONS.PAV.RODOV.-DAER 2892201.0
FISCAL.DE SERV.CONCEDIDOS 2797213.0
TRANSPORTE DE PESSOAS 2056261.0
PARTICIPACAO-EVENTOS 1971834.0
REUNIOES ADMINISTRATIVAS 1929856.0
ADMINISTRATIVO MP 1711359.0
SERV.PATRULH.RODOVIARIO 1629358.0
SERVICOS GERAIS 1623286.0
A SERVICO DE DEPUTADO 1527813.0
DEPUT.EST. A SERV.MANDATO 1309648.0
REUNIOES TECNICAS 1261205.0
ESCOLTA PRESOS -REMOCAO 1013571.0
PARTICIP-SEMINARIOS/CONGR 970380.0
SERV.DE ADMINISTR.-DAER 913763.0
Name: Valor, dtype: float64
Aqui, cruzamos destinos e servidores associados:
df.groupby(['Destino','Favorecido2'])['Valor'].sum().nlargest(20).round()
Destino Favorecido2
PORTO ALEGRE SILVA 1163673.0
SANTOS 551193.0
MACHADO 408099.0
OLIVEIRA 378335.0
TRAMANDAI SILVA 357969.0
PORTO ALEGRE PEREIRA 296562.0
ROSA 256169.0
CAPAO DA CANOA SILVA 253770.0
PORTO ALEGRE LIMA 245712.0
JUNIOR 227397.0
SOUZA 225926.0
TORRES SILVA 214180.0
PORTO ALEGRE RODRIGUES 207616.0
TRAMANDAI OLIVEIRA 193649.0
PORTO ALEGRE ALMEIDA 175780.0
MORAES 174702.0
SILVEIRA 171049.0
TRAMANDAI SANTOS 170904.0
PORTO ALEGRE COSTA 159793.0
CIDREIRA SILVA 151463.0
Name: Valor, dtype: float64
Agora, vejamos quais foram os maiores valores reservados a determinado servidor em 2017:
x = df.sort_values(by='Valor', ascending=False).loc[:10,['Orgao','Favorecido2','Destino','Motivo','Valor']]
x.head(10)
Orgao | Favorecido2 | Destino | Motivo | Valor | |
---|---|---|---|---|---|
158461 | SECRETARIA DE DESENVOLVIMENTO ECONOMICO, CIENC... | FONTANA | EXTERIOR | MISSAO OFICIAL | 14056.90 |
210104 | ASSEMBLEIA LEGISLATIVA | DZIEDRICKI | PARIS - FRANCA. DIARIAS ESPECIAIS DE VIAGEM | DEPUT.EST. A SERV.MANDATO | 13800.24 |
610 | ASSEMBLEIA LEGISLATIVA | LOPES | PARIS - FRANCA DIARIAS ESPECIAIS DE VIAGEM | DEPUT.EST. A SERV.MANDATO | 13555.60 |
26539 | ASSEMBLEIA LEGISLATIVA | SIMONI | Basileia - SUICA DIARIAS ESPECIAIS DE VIAGEM | DEPUT.EST. A SERV.MANDATO | 13468.00 |
196248 | SECRETARIA DO AMBIENTE E DESENVOLVIMENTO SUSTE... | PELLINI | EXTERIOR | PARTICIPACAO-EVENTOS | 13019.26 |
210715 | SECRETARIA DO AMBIENTE E DESENVOLVIMENTO SUSTE... | MOLLMANN | EXTERIOR | PARTICIPACAO-EVENTOS | 13019.26 |
207645 | SECRETARIA DO AMBIENTE E DESENVOLVIMENTO SUSTE... | MEIRELLES | EXTERIOR | PARTICIPACAO-EVENTOS | 13019.26 |
163526 | SECRETARIA DE DESENVOLVIMENTO ECONOMICO, CIENC... | SCHUNEMANN | EXTERIOR | MISSAO OFICIAL | 12521.29 |
198315 | ASSEMBLEIA LEGISLATIVA | BECKER | BONN - ALEMANHA. DIARIAS ESPECIAIS DE VIAGEM | DEPUT.EST. A SERV.MANDATO | 12370.24 |
196438 | SECRETARIA DE DESENVOLVIMENTO ECONOMICO, CIENC... | SCHAFER | EXTERIOR | PARTICIPACAO-EVENTOS | 11593.73 |
A seguir, veremos quais servidores requisitaram o maior número de diárias/passagens:
x = df.groupby(['Cod_Credor','Favorecido2'])
ind = x.size().nlargest(10).reset_index()
ind
Cod_Credor | Favorecido2 | 0 | |
---|---|---|---|
0 | 6137113 | DENKVITTS | 192 |
1 | 21180091 | DIAS | 190 |
2 | 20682816 | LERMEN | 188 |
3 | 21164762 | RAMOS | 188 |
4 | 21169330 | RODRIGUES | 188 |
5 | 21153450 | MARCO | 181 |
6 | 26210711 | WITT | 180 |
7 | 26079267 | COUTO | 179 |
8 | 21171416 | IRENO | 178 |
9 | 21187487 | RAMOS | 178 |
Mais de 180 dias! Lembrando que o calendário comercial tem 252 dias no ano. Podemos cruzar a base ind
gerada acima com a base de dados original df
para calcular a diária média paga para estes servidores:
x = ind.merge(df)
x.groupby(['Cod_Credor','Favorecido2']).mean()['Valor']
Cod_Credor Favorecido2
6137113 DENKVITTS 143.500000
20682816 LERMEN 61.500000
21153450 MARCO 88.002597
21164762 RAMOS 61.500000
21169330 RODRIGUES 61.500000
21171416 IRENO 61.500000
21180091 DIAS 61.500000
21187487 RAMOS 61.500000
26079267 COUTO 80.963128
26210711 WITT 64.916389
Name: Valor, dtype: float64
x.groupby('Mes').mean()['Valor']
Mes
1 143.500000
2 84.204194
3 78.925000
4 75.089494
5 80.033904
6 71.261429
7 76.178333
8 70.804043
9 72.729108
10 75.749390
11 72.090350
12 72.155921
Name: Valor, dtype: float64
Vamos acompanhar a evolução dos gastos destes servidores, mês a mês:
y = pd.DataFrame(x.groupby(['Mes','Favorecido2'])['Valor'].sum())
y.unstack().plot(kind='line', subplots=False)
<matplotlib.axes._subplots.AxesSubplot at 0x21235266c50>
Até aqui exploramos os gastos em termos de valores. Vamos agora para a frequência das requisições de diárias! Os dados disponibilizados pelo Portal da Transparência informam as datas iniciais e finais associadas à cada empenho (nas variáveis DataInicio
e DataFim
) bem como a quantidade de diárias pagas (nas variáveis Quantidade
e QuantidadeMeia
). Meias diárias são pagas quando não há pernoite do servidor.
Com essas informações, é possível comparar a quantidade de diárias pagas com as datas registradas, bem como identificar o dia da semana.
df['DataInicio'] = pd.to_datetime(df.DataInicio, format='%d/%m/%Y')
df['DataFim'] = pd.to_datetime(df.DataFim, format='%d/%m/%Y')
df['QuantosDias'] = df['DataFim'] - df['DataInicio']
df['QuantosDias'] = df.QuantosDias.dt.days
Vamos ver as viagens transcorridas durante finais de semana. Para isso, criarei uma função que indica se há um sabado ou domingo num intervalo entre datas, retornando verdadeiro ou falso, e depois aplicaremos essa função nos nossos dados.
def sabdom(x):
"""Retorna True se há sábado ou domingo num intervalo entre datas"""
a = pd.date_range(start=x['DataInicio'], end=x['DataFim'], freq='D').dayofweek # dias entre inicio e fim da diaria
b = np.in1d(a, [5,6]).any() # 5 = sábado, 6 = domingo
return b
df.apply(sabdom, axis=1)
Deu erro! Isto acontece pois temos alguns valores faltantes em DataInicio
e DataFim
. Vamos criar uma versão dessa base sem esses valores e tentar novamente:
df2 = df.dropna()
x = df2.apply(sabdom, axis=1)
df2['SabDom'] = x
df2.SabDom.value_counts()/len(df2)
False 0.798103
True 0.201897
Name: SabDom, dtype: float64
Segundo o cálculo acima, em 20% dos casos, a diária transcorre sábados e domingos. Podemos analisar os motivos associados com a função pivot_table
:
tab = df2.pivot_table('Quantidade', index='Motivo', columns='SabDom', aggfunc=np.count_nonzero, margins=True, fill_value=0)
tab.head()
SabDom | False | True | All |
---|---|---|---|
Motivo | |||
A SERV.COMIS.TECN.PERMAN. | 81 | 42 | 123 |
A SERVICO DE DEPUTADO | 863 | 847 | 1710 |
A SERVIÇO DA FASE | 1 | 0 | 1 |
ACOMP.DE INVENT.DE B.MOV. | 43 | 8 | 51 |
ACOMP.DE INVENT.DE ESTOQ. | 0 | 0 | 0 |
Acima, temos a contagem de dos casos para cada motivo. Podemos criar uma coluna para analisar a frequência de casos positivos em relação ao total:
tab['Percent'] = tab[True]/tab['All']
tab.sort_values(by='Percent', ascending=False, inplace=True)
#tab.sort_values(by=['Percent'], axis=1, inplace=True)
tab.head(20)
SabDom | False | True | All | Percent |
---|---|---|---|---|
Motivo | ||||
ATEND.REPART.FISC./EXAT. | 0 | 1 | 1 | 1.000000 |
CONTATOS COMUNIDADE | 0 | 1 | 1 | 1.000000 |
FISCALIZACAO TAXA CDO | 0 | 49 | 49 | 1.000000 |
OPERAC. TURISMO/FRONTEIRA | 0 | 30 | 30 | 1.000000 |
RESSARC SERVIDOR BPR DAER | 1 | 7590 | 7591 | 0.999868 |
OPERACAO LITORAL | 221 | 10049 | 10270 | 0.978481 |
MUTIRAO CARTORARIO | 6 | 265 | 271 | 0.977860 |
OPERACAO CANARINHO | 52 | 2094 | 2146 | 0.975769 |
PERFURACAO DE POCOS | 11 | 207 | 218 | 0.949541 |
SERV.PATRULH.RODOVIARIO | 138 | 1272 | 1410 | 0.902128 |
REFORCOS A OUTRA OPM | 913 | 4701 | 5614 | 0.837371 |
APOIO EQUIPES FISCALIZ | 10 | 51 | 61 | 0.836066 |
TRANSF.P/NECESSID.SERVICO | 9 | 21 | 30 | 0.700000 |
FISC. TRANSITO DE MERCAD. | 6 | 14 | 20 | 0.700000 |
REF.A EVENTOS ESPEC. - BM | 158 | 365 | 523 | 0.697897 |
INSPECAO SANITARIA/ANIMAL | 7 | 13 | 20 | 0.650000 |
FISCALIZ/PATRULHA AMBIENT | 3 | 5 | 8 | 0.625000 |
COMBATE AO ABIGEATO | 23 | 35 | 58 | 0.603448 |
SUBSTITUICOES A FUNCION. | 150 | 222 | 372 | 0.596774 |
ESTAGIOS | 3 | 4 | 7 | 0.571429 |
Portanto, vemos que a maioria das diárias de fim de semana está de fato ligada à atividades de campo de servidores.
A tabela a seguir faz a tabulação cruzada entre número de diárias pagas e dias transcorridos de viagem, com o uso da função pivot_table
:
tab = df.pivot_table(index='Quantidade', columns='QuantosDias', aggfunc=np.count_nonzero)
tab.head(10)
Cod_Credor | ... | Valor | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
QuantosDias | 0.0 | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 | 6.0 | 7.0 | 8.0 | 9.0 | ... | 61.0 | 69.0 | 77.0 | 92.0 | 96.0 | 154.0 | 168.0 | 273.0 | 304.0 | 340.0 |
Quantidade | |||||||||||||||||||||
0 | 153006.0 | 4295.0 | 1444.0 | 710.0 | 603.0 | 68.0 | 41.0 | 30.0 | 42.0 | 23.0 | ... | 1.0 | 1.0 | 1.0 | 1.0 | 2.0 | NaN | 2.0 | 2.0 | 1.0 | 2.0 |
1 | 725.0 | 39429.0 | 336.0 | 58.0 | 54.0 | 7.0 | NaN | 1.0 | 1.0 | NaN | ... | NaN | NaN | NaN | NaN | NaN | 3.0 | NaN | NaN | 1.0 | NaN |
2 | 19.0 | 189.0 | 15437.0 | 194.0 | 122.0 | 8.0 | NaN | 3.0 | 1.0 | 2.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
3 | 17.0 | 6.0 | 76.0 | 6487.0 | 177.0 | 7.0 | 2.0 | 2.0 | 4.0 | 2.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
4 | 7.0 | 1.0 | NaN | 608.0 | 6745.0 | 25.0 | 4.0 | 2.0 | 4.0 | 3.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
5 | 4.0 | 1.0 | NaN | NaN | 50.0 | 2516.0 | 4.0 | 7.0 | 2.0 | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
6 | 4.0 | NaN | NaN | NaN | 1.0 | 372.0 | 507.0 | 1.0 | 16.0 | 10.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
7 | NaN | NaN | NaN | 1.0 | NaN | NaN | 136.0 | 379.0 | 4.0 | 10.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
8 | NaN | NaN | NaN | NaN | NaN | NaN | 9.0 | 82.0 | 140.0 | 1.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
9 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 116.0 | 174.0 | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
10 rows × 1134 columns
Na tabela acima podemos detectar alguns pontos fora da curva, como por exemplo, várias diárias pagas para atividades de um dia, e vice-versa.
tab = df.query('(Quantidade > 1 ) & (QuantosDias == 1)').loc[:,['Favorecido2','Quantidade','Valor']]
tab.head(20)
Favorecido2 | Quantidade | Valor | |
---|---|---|---|
2698 | ROLIM | 2 | 245.98 |
2746 | SENNA | 2 | 245.98 |
6363 | SILVA | 2 | 245.98 |
6958 | PEREIRA | 2 | 245.98 |
6996 | MELLO | 2 | 245.98 |
7041 | WEBER | 2 | 245.98 |
7177 | DIAS | 2 | 245.98 |
7234 | MOURA | 2 | 245.98 |
7380 | CARVALHO | 2 | 245.98 |
8409 | SOUTO | 2 | 245.98 |
11116 | POZZOBON | 2 | 358.75 |
11125 | SILVA | 2 | 245.98 |
11173 | MACHADO | 2 | 245.98 |
14233 | MARTINS | 2 | 245.98 |
14274 | GUIMARAES | 2 | 245.98 |
14338 | ROCHA | 2 | 245.98 |
14341 | RITTER | 2 | 245.98 |
14520 | SOUZA | 2 | 245.98 |
14976 | CAMPOS | 2 | 245.98 |
15600 | MACHADO | 2 | 245.98 |
Vamos organizar por quantidade de diárias para entender melhor:
tab = tab.sort_values(by='Quantidade', ascending=False)
tab.head(20)
Favorecido2 | Quantidade | Valor | |
---|---|---|---|
80827 | MOIANO | 29 | -184.49 |
28505 | FLORES | 18 | -738.00 |
257107 | BRUNHAUSER | 14 | -122.99 |
168131 | SILVA | 14 | -150.32 |
190620 | SERPA | 5 | -123.00 |
27416 | PERIN | 4 | 526.12 |
222709 | SOBROSA | 3 | -245.98 |
105213 | PALADINI | 3 | 2234.31 |
155972 | SOUZA | 3 | -300.66 |
41910 | MATTAR | 3 | 698.75 |
24447 | MACHADO | 3 | 512.48 |
43525 | LUZ | 3 | 698.75 |
226281 | FIORAVANSO | 2 | 245.98 |
100498 | RESCHKE | 2 | 1560.00 |
101771 | MEIRELLES | 2 | 1560.00 |
102686 | ROSSI | 2 | 245.98 |
102695 | VARGAS | 2 | 245.98 |
246512 | ALIARDI | 2 | 245.98 |
111185 | BIANCHI | 2 | 540.00 |
112748 | PIRES | 2 | 123.00 |
Tudo certo! Aparentemente, a maioria dos registros trata de ressarcimentos.
Por enquanto, vamos parando por aqui! Entretanto, muito mais pode ser feito, e este exercício mostrou apenas algumas das capacidades de manipulação e cruzamento de dados com o Python, através do pacote pandas
.