Abrindo arquivos Excel em Python: explorando a performance de diferentes algoritmos

Anderson Eduardo
7 min readJul 3, 2020
Photo by Mika Baumeister on Unsplash

Manter-se atualizado quanto à tecnologia e boas práticas sobre manipulação de dados é uma atividade quase que rotineira para data scientists e data engineers. Entretanto, conhecer e adquirir vivência com as ferramentas e pipelines mais sofisticados pode não ser suficiente para lidar com todos os diferentes desafios cotidianos dos projetos em que atuamos. Um bom exemplo disso é o uso de planilhas Excel como fonte de dados e, também, como veículo para entregar resultados à usuários e clientes.

Falando especificamente de Python, qualquer pessoa que tenha se aventurado pelos caminhos da ciência de dados certamente terá em mente a biblioteca Pandas como uma ferramenta padrão para lidar com a importação de dados de diferentes fontes para “dentro” do ambiente Python. De fato, Pandas tornou-se a forma canônica para esse tipo operação (e muitas outras mais!). No entanto, tratando-se de planilhas Excel, está longe de serem raros os casos em que temos que lidar com arquivos complexos de inúmeras abas, dezenas de colunas e milhares (talvez centenas de milhares) de linhas nas planilhas. Nesses casos, torna-se interessante explorar outras ferramentas além do “read_excel” e “ExcelFile” do Pandas.

Neste artigo, as principais ferramentas de importação de dados a partir de arquivos Excel serão apresentadas e analisadas quanto a sua performance. Espero que, ao fim, o leitor tenha uma visão mais informada sobre esse tipo de input de dados para dentro do ambiente de programação Python.

Python & Excel

Uma das melhores iniciativas para trabalhar com arquivos Excel em Python é o projeto Python-Excel (http://www.python-excel.org/). Esse site disponibiliza informações sobre as mais importantes libraries Python para tal finalidade. Aqui, usarei as libraries indicadas nele como referência. A seguir, discorrerei sobre as opções disponíveis para leitura de dados a partir de arquivos Excel. Para todos os exemplos, usarei Python 3.7.6, sempre com instalação de pacotes através do pip (caso não esteja familiarizado, veja este link).

Pandas

Pandas é uma das bibliotecas mais importantes atualmente para qualquer desenvolvedor Python que precise manipular dados estruturados. As estruturas de dados DataFrame e Series já são o padrão para o desenvolvimento de projetos de ciência de dados usando Python. Conforme já mencionado anteriormente, o Pandas possui as funções read_excel e ExcelFile, que permitem ler um arquivo Excel de um modo bastante confortável. A sintaxe não poderia ser mais simples (e “pythonica”):

>>> import pandas as pd
>>> df = pd.read_excel(“/caminho até meu arquivo excel/arquivo.xlsx”)

O objeto df conterá a planilha do arquivo endereçado. Caso existam múltiplas planilhas, a primeira será aberta por padrão. Para especificar qual das planilhas desejamos ler, basta adicionar o parâmetro sheet_name:

>>> df = pd.read_excel(“/caminho até meu arquivo excel/arquivo.xlsx”, sheet_name=” custos”)

O Pandas também disponibiliza a função ExcelFile, com a seguinte sintaxe:

>>> xl = pd.ExcelFile(“/caminho até meu arquivo excel/arquivo.xlsx”)

Nesse código, xl pode ser entendido como um objeto computacional do arquivo. Para abrir uma das planilhas de modo a possibilitar efetivamente o uso dos dados, fazemos:

>>> df = xl.parser(“custos”)

Ou ainda, podemos concatenar essas duas partes em uma única:

>>> df = pd.ExcelFile(“/caminho até meu arquivo excel/arquivo.xlsx”).parser(“custos”)

A princípio, esses comandos são todos equivalentes (veja aqui). Como o objetivo aqui é explorar a performance de diferentes algoritmos de leitura de arquivo, não avançarei sobre as diferentes possibilidades de parametrização. Para maiores detalhes, veja a documentação (neste link).

openpyxl

Depois do Pandas, o openpyxl é apontado como módulo mais recomendado para trabalhar com arquivos Excel. De acordo com a documentação, o módulo foi pensado mais especificamente para trabalhar com Excel 2010. Vale ressaltar que não é necessário ter o Excel instalado e nem estar trabalhando em sistema operacional Windows para que a library possa ser utilizada.

A sintaxe do openpyxl é mais prolixa do que a do Pandas. Por outro lado, essa é uma library bastante abrangente em termos das possibilidades de manipulação de arquivos Excel. Para abrir um arquivo, fazemos:

>>> import openpyxl>>> wb = openpyxl.load_workbook(filename=”/caminho até meu arquivo excel/arquivo.xlsx”)

Nesse exemplo, wb é o “workbook”, ou objeto “arquivo Excel” dentro do ambiente Python. Para efetivamente obter os dados das planilhas, precisamos “navegar” pelas estruturas desse objeto. Por exemplo, para visualizarmos as planilhas usamos:

>>> wb.sheetnames

De forma simples, podemos acessar os valores dessa planilha da seguinte forma:

>>> for d in wb['sheet_1'].iter_rows(values_only = True):        print(d)

Aqui, a variável d será uma tupla, contendo os valores de uma linha da planilha Excel. Para acessarmos todas as planilhas, precisamos iterar sobre os nomes delas, conforme este exemplo:

>>> for sheet in wb.sheetnames:        for d in wb[sheet].iter_rows(values_only=True):            print(d)

Como é bastante comum na prática, pode ser necessário abrir as planilhas como um DataFrame. Seguindo a lógica apresentada, poderíamos fazer:

>>> dict_dfs = {}>>> for sheet in wb.sheetnames:        sheet_data = []        for d in wb[sheet].iter_rows(values_only=True):            sheet_data.append(d)            dict_dfs[sheet] = pd.DataFrame(sheet_data, columns=sheet_data[0]).drop(0, axis=0)

Vale ressaltar (mais uma vez) que o openpyxl é um módulo bastante abrangente em recursos, mas aqui me limitarei ao objetivo de explorar a performance ao abrir arquivos Excel. Para uma texto que explore de forma mais geral e com exemplos, sugiro este excelente artigo.

xlrd

Este é uma importante alternativa às libraries anteriores. De acordo com a documentação, o xlrd foi desenvolvido mais especificamente para ser capaz de ler arquivos mais antigos do Excel (i.e., arquivos da extensão “xls”). A sintaxe para abertura de arquivos é semelhante àquela do openpyxl, conforme o exemplo:

>>> import xlrd>>> wb = xlrd.open_workbook(”/caminho até meu arquivo excel/arquivo.xlsx”)>>> for i in range(wb.sheet_by_name('sheet_1').nrows):        print(wb.sheet_by_name('sheet_1').row_values(i))

Esse código retornará na tela os valores da planilha “sheet_1”. Para abrirmos múltiplas abas do Excel e para armazenarmos os dados em DataFrames do Pandas, também seguimos uma linha de raciocínio similar àquela do openpyxl:

>>> dict_dfs = {}>>> for sheet in wb.sheet_names():      sheet_data = []      for i in range(wb.sheet_by_name(sheet).nrows):        sheet_data.append(wb.sheet_by_name('sheet_1').row_values(i))        dict_dfs[sheet] = pd.DataFrame(sheet_data,        columns=sheet_data[0]).drop(0, axis=0)

Para maiores detalhes sobre as possibilidades de parametrização e outras funções desse módulo veja a documentação.

Função autoral

Em termos simples, um arquivo Excel pode ser entendido como um conjunto de arquivos XML. Assim, uma alternativa adicional seria construir uma função para ler e navegar pelos XMLs, extraindo os dados. Claro que construir uma função robusta aos diferentes tipos de informação contidas em um arquivo Excel (como fórmulas, por exemplo) é uma tarefa desafiadora. Mas, dado o intuito de análise exploratória deste artigo, incluirei aqui uma função que abre dados simples (como os dados artificiais usados nas análises deste artigo). Essa função foi elaborada a partir de diversas sugestões de fóruns e demais textos de blogs especializados. Discorrer sobre os detalhes da leitura e manipulação de arquivos XML foge do escopo do presente artigo, por isso tratarei deste assunto em um próximo artigo. Por ora, o código da função pode ser obtido neste link.

Performance

Agora que cada library já foi apresentada, podemos seguir com as comparações de performance de cada um deles para abrir arquivos Excel, considerando diferentes tamanhos. Para isso, funções foram implementadas para invocar os candidatos e contabilizar o tempo gasto por eles em diferentes cenários (i.e., diferentes tamanhos de arquivo Excel). Os arquivos Excel contêm dados artificiais, criados especificamente para os testes. Os cenários envolvem arquivos com 20, 200, 2000, 20000 linhas, 20 colunas e 1, 5 e 10 abas. Cada cenário foi replicado 5 vezes (tendo em vista capturar a estocasticidade da geração dos dados). O código completo pode ser obtido aqui neste link.

Abaixo, podemos visualizar os resultados:

Resultado dos experimentos computacionais usando as diferentes funções de carregamento de dados de arquivos Excel, conforme apresentado no texto das seções anteriores. Cada ponto no gráfico representa o tempo gasto pelo algoritmo para abrir os dados de um arquivo específico (aqui, a variação do número de linhas nos arquivos pode ser identificada no eixo x). As linhas são regressões lineares, sendo a área sombreada o intervalo de confiança de 95%.
Mesmos resultados que no gráfico anterior, só que agora mostrando a variação do número de abas nos arquivos no eixo x.

Como podemos verificar as funções de todos os pacotes mostram um crescimento linear com o aumento no volume de dados nos arquivos. Também observa-se que, em média, o Pandas tende a ser a opção menos eficiente. Entre as libraries, o openpyxl parece ser ligeiramente mais eficiente que as demais. Contudo, a função autoral exibiu performance claramente superior em relação às demais funções. Isso ilustra que, ao menos para dados simples (por exemplo, sem equações nas planilhas de Excel), vale a pena investir em abrir o arquivo Excel através da manipulação direta de seus arquivos XML.

Considerações finais

Neste artigo foram comparadas as performances das principais funções para importar dados de arquivos Excel para dentro do ambiente de programação Python. Usando arquivos de diferentes tamanhos (em termos de número de linhas e número de abas), os resultados obtidos mostram que utilizar o Pandas (i.e., a ferramenta padrão para este tipo de operação) não é a opção mais eficiente para arquivos maiores. Entre as libraries, a openpyxl parece fornecer a função mais eficiente. No entanto, importar os dados iterando sobre os arquivos XML trata-se da alternativa mais eficiente. Em conclusão, os testes mostraram que, para arquivos menores, o Pandas pode ser utilizado sem maiores problemas de performance. Para arquivos maiores e mais complexos, vale a pena investir em formas alternativas de leitura de dados.

--

--