top of page
  • Foto do escritorGabriel Quintella

Python, Manipulando Grandes Arquivos

Fala meu amigo, tudo bem com você?


Você já pensou em trabalhar com grandes volumes de dados usando a linguagem Python para processamento dos dados? Pois bem, esse é um assunto que dedico um grande tempo estudando. Vejo em muitas lives que o Python é muito bom, que possui um grande aceite para projetos de Data Science e por os elogios a essa grande linguagem não param.


Como ainda sou iniciante em Python, confesso que não conseguia ver essa performance que todos comentam. Porém, após algumas pesquisas, identifiquei que estava direcionando meus estudos de forma errada e que precisava dedicar um tempo maior no aprofundamento da documentação Python, recomendo muito isso pra ti!


Após essa investida na documentação, tomei conhecimento de um parâmetro que é configurado na função pandas.read_csv, o nome desse parâmetro é chunksize e pasmem, consegui surfar nas tão desejadas big waves graças ao chunksize!


Beleza, depois de ler esse pequeno trecho tenho certeza que algumas interrogações estão saltitando na sua mente e você está querendo saber o que esse tal de chunksize faz, ou o que ele fez no meu caso, estou certo?


Pois bem, vou tentar resumir o seu beneficio e no código que trago como exemplo, explorarei um pouco mais os benefícios do chunksize.


Se formos falar um português bem direto, o chunksize atua quebrando o seu conjunto de dados em subconjuntos e realiza a sua leitura por pedaços.


Vamos analisar o exemplo abaixo que retirei do site Geeks For Geeks.


Inicialmente ele importa um arquivo train.csv.


import pandas as pd
from pprint import pprint

df = pf.read_csv('train/train.csv')

df.columns

Usando a função pandas.dataframe.info() é possível visualizar a estrutura do dataframe e com isso que esse arquivo possui 159571 linhas.



O próximo passo é refazer a leitura do mesmo arquivo porém agora usando o parâmetro chunksize, particionando o arquivo em pedaços menores de 10000 linhas.


df = pd.read_csv("train/train.csv", chunksize=10000)
print.print(df)

Após realizar essa operação, podemos verificar como que ficarão os blocos durante o processo na fase de importação, para isso usamos a função shape combinando dentro de um laço de repetição FOR.


for data in df:
	print(data.shape)


Na imagem acima, a primeira coluna representa a quantidade de linhas e a segunda a quantidade de colunas. Em resumo, esse arquivo possui 159571 linhas, quando particionados em blocos de 10000 linhas, 15 blocos de 10000 linhas e um bloco com 9571 linhas são criados.


Sei que até aqui você está pensando, pow 160000 linhas é um grande arquivo? Lógico que não e falo nem precisa carregar usando o chunksize.


Agora vamos agora surfar em nossa Big Wave dos dados.


Primeiro passo foi ir em busca das Big Waves (grande arquivos). Confesso que isso não foi uma atividade complexa, pois durante a pandemia realizei alguns estudos levando como base os dados do Covid19 e de vacinação, parei exatamente com os estudos justamente pelo fator de não conseguir manipular os arquivos que foram crescendo com o passar dos dias.


Para que você possa ter acesso as mesmas informações, basta acessar o site do DataSUS e no meu caso, usei os dados do Estado de São Paulo. No momento que escrevo esse post (11/08/2022), são 3 arquivos como aproximadamente 21 Gb cada, totalizando quase 140 milhões de registros (134.005.978).


Após o download desses arquivos, analisei a documentação e identifiquei que esse dataset possui 32 colunas e para concluir a análise, mapeei apenas das colunas que pretendo trabalhar.


Vamos analisar como que ficou o código?


diretorio = 'C:\\Temp\\Covid19\\Vacina_Arquivos_SP'

dfVacina = pd.DataFrame()

for arquivoVacina in os.listdir(diretorio):
    
    arquivo = os.path.join(diretorio, arquivoVacina) 

    print(arquivo)
    
    data_inicial = datetime.datetime.now()
    
    chunk = pd.read_csv(arquivo
                     ,sep=';'
                     ,usecols=[1,4,9,10,11,13,27,28,30]
                     ,names=['paciente_id'
                             ,'paciente_enumSexoBiologico'
                             ,'paciente_endereco_nmMunicipio'
                             ,'paciente_endereco_nmPais'
                             ,'paciente_endereco_uf'
                             ,'paciente_nacionalidade_enumNacionalidade'
                             ,'vacina_dataAplicacao'
                             ,'vacina_descricao_dose'
                             ,'vacina_nome']
                     ,dtype={'paciente_id':'str'
                             ,'paciente_enumSexoBiologico':'str'
                             ,'paciente_endereco_nmMunicipio':'str'
                             ,'paciente_endereco_nmPais':'str'
                             ,'paciente_endereco_uf':'str'
                             ,'paciente_nacionalidade_enumNacionalidade':'str'
                             ,'vacina_dataAplicacao':'str'
                             ,'vacina_descricao_dose':'str'
                             ,'vacina_nome':'str'}
                     ,engine='python'
                     ,chunksize=1000000)
                     
    df = pd.concat(chunk)
        
    df['arquivo'] = arquivo
    df['data_inicial'] = data_inicial
    df['data_final'] = datetime.datetime.now()
    
    dfVacina = dfVacina.append(df)
    

Comentando o código acima, possuímos as seguintes informações:


1 - Definimos uma variável que será responsável por receber o caminho dos arquivos;

2 - Criamos um dataset vazio;

3 - Como são 3 arquivos, inclui essa rotina dentro de uma rotina FOR permitindo assim a leitura de um arquivo por vez;

4 - Dentro da função pandas.read_csv(), defini quais as colunas que pretendo carregar, defini o datatype de cada coluna, o separador de linhas, e defini que a leitura do arquivo deverá ser realizada de forma particionada em blocos de 1.000.000 de linhas cada vez (tentei diminuir a quantidade de linhas porém a performance caiu);

5 - Utilizo a função pandas.concat() para juntar as partes importadas e usando pandas.append() vou armazenando os dados dentro do meu dataframe que defini logo no inicio;

6 - Após a importação, incluo 3 novas colunas no arquivo apenas como forma de controle do processo (nome do arquivo, data/hora de inicio e fim da importação).


Além desse código, realizei o desenvolvimento de outro para analisar o uso/alocação de memória durante o processamento.


import psutil 
import time 
import datetime

v_ini = '1'
conteudo = '1'

controleMemoriaCPU = open('controleMemoriaCPU.txt','w')

while v_ini == conteudo:

    time.sleep(15)
    
    arquivoControle = open('controle.txt','r')
    conteudo = arquivoControle.read()
    
    controleMemoriaCPU.write('{0};{1}'.format(psutil.virtual_memory()[2],datetime.datetime.now()))
    controleMemoriaCPU.write("\n")

controleMemoriaCPU.close()

Durante a execução, os dados são capturados a cada 15 segundos e no seu término gero um gráfico para visualizar esse consumo de recurso.



Analisando o gráfico acima, é possível visualizar alguns picos, porém em sua grande parte, o consumo ficou em torno de 80%.


Bem meu amigo, com isso concluo esse post. Espero ter contribuído para o seu estudo caso tenha encontrado o mesmo problema que eu encontrei durante as minhas jornadas de estudo.


Deixo no GitHub os arquivos do notebook que usei nesse estudo.


Grande abraço e até a próxima!

192 visualizações0 comentário

Posts recentes

Ver tudo

Comments


bottom of page