segunda-feira, 10 de agosto de 2020

Analise de dados com pandas

Photo by Isaac Smith on Unsplash

Introdução

Como analista de dados, você precisar analisar os passos que você executa quando encontra um conjunto de dados pela primeira vez. Essa analise deve ser feita logo após ser criado o dataframe. O que você deve se perguntar é: existe alguma rotina que você segue quando encontra um dataset novo? Você sabe quais são os tipos de dados presentes no dataframe? Esse post da inicio a uma série de tutoriais do que fazer quando encontrar um dataset novo. Nessa série vamos responder perguntas comuns sobre coisas que não são simples de fazer com pandas.

Rotina de analise de dados

Não existe um padrão estabelecido do que deve ser feito quando encontramos um dataset pela primeira vez. Uma boa ideia é desenvolver a sua própria rotina do que fazer com um dataset na primeira vez. Assim como temos uma rotina para outras tarefas na nossa vida, como fazer uma lista de compras antes de ir ao supermercado, devemos ter uma rotina para quando obtemos um dataset novo. Essa rotina vai te ajudar nos passos seguintes. Essa rotina pode ser uma lista que coisas que você acha útil fazer com um dataset novo. A lista pode se expandir ou diminuir com o tempo, o que vai definir isso é o beneficio que você vai obter com cada tarefa.
Análise exploratória de dados (AED) é muito utilizada para descrever o processo de analise de conjuntos de dados (datasets). Esse processo não engloba a criação de modelos, mas sim a analise a fim de descobrir as principais características e a melhor forma de visualizar esses dados.
Os processos utilizados na analise exploratória de dados são uteis para entender um conjunto de dados. Esses processos são muito utilizados para descobrir qual é a melhor maneira de criar e treinar modelos de aprendizagem de máquina.
Nesse tutorial vamos aprender uma pequena, mas fundamental, parte da Análise exploratória de dados: A coleta de dados e estatísticas do dataset. Aqui vamos descrever uma lista de tarefas que podem ser uteis quando importamos um dataset pela primeira vez. Você pode adicionar os métodos, que vamos mostrar, na sua própria rotina de analise de dados.
Os métodos, utilizados nesse tutorial, descrevem os dados sobre os dados. Vamos aprender a obter algumas informações básicas, como a quantidade de colunas e seus nomes, tipo de dados da coluna entre outros.

Como começar a analise de dados

Primeiro precisamos de um dataset. Os dataset que vamos utilizar podem ser encontrados aqui. Depois vamos pegar algumas amostras do dataframe com o método sample(). Para essas amostras serem mais realistas vamos pegar oito amostras de forma aleatória. Utilizando o parâmetro n para informar a quantidade de amostras e o parâmetro random_state para informar o número que deve ser utilizado na geração de números aleatórios (pseudoaleatórios).

>>> import pandas as pd
>>> animelist = pd.read_csv('animelist.csv')
>>> animelist.sample(n=8, random_state=42)
       anime_id  ...                     ending_theme
12334     12133  ...                               []
8366       8619  ...                               []
1795      18967  ...                               []
7100      36121  ...                               []
6050       8157  ...                               []
14198     35104  ...                               []
8028      33201  ...                               []
1730       1005  ...  ['"Hearts" by Saori Nishihata']

[8 rows x 31 columns]

Para saber a forma do dataframe vamos chamar o atributo shape. Esse atributo retorna uma tupla com a forma do dataframe. O primeiro elemento da tupla é o número de linhas e o segundo o número de colunas.

>>> animelist.shape
(14478, 31)

Chamando o método info() conseguimos algumas informações. Esse método nos mostra o nome de cada coluna, a quantidade de elementos não vazios e o tipo de dado de cada coluna. E ainda nos informa a quantidade de memoria que o dataframe está utilizando.

>>> animelist.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 14478 entries, 0 to 14477
Data columns (total 31 columns):
 #   Column          Non-Null Count  Dtype
---  ------          --------------  -----
 0   anime_id        14478 non-null  int64
 1   title           14478 non-null  object
 2   title_english   5724 non-null   object
 3   title_japanese  14443 non-null  object
 4   title_synonyms  8937 non-null   object
 5   image_url       14382 non-null  object
 6   type            14478 non-null  object
 7   source          14478 non-null  object
 8   episodes        14478 non-null  int64
 9   status          14478 non-null  object
 10  airing          14478 non-null  bool
 11  aired_string    14478 non-null  object
 12  aired           14478 non-null  object
 13  duration        14478 non-null  object
 14  rating          14478 non-null  object
 15  score           14478 non-null  float64
 16  scored_by       14478 non-null  int64
 17  rank            12904 non-null  float64
 18  popularity      14478 non-null  int64
 19  members         14478 non-null  int64
 20  favorites       14478 non-null  int64
 21  background      1057 non-null   object
 22  premiered       4096 non-null   object
 23  broadcast       4271 non-null   object
 24  related         14478 non-null  object
 25  producer        8288 non-null   object
 26  licensor        3373 non-null   object
 27  studio          8544 non-null   object
 28  genre           14414 non-null  object
 29  opening_theme   14478 non-null  object
 30  ending_theme    14478 non-null  object
dtypes: bool(1), float64(2), int64(6), object(22)
memory usage: 2.1+ MB

Se você estiver precisando saber as estatísticas básicas do dataframe é só chamar o método describe(). Esse método nos fornece as estatísticas básicas de cada coluna. Com o parâmetro include especificamos de quais colunas queremos as estatísticas.

>>> import numpy as np
>>> animelist.describe(include=np.number)
           anime_id      episodes  ...       members      favorites
count  14478.000000  14478.000000  ...  1.447800e+04   14478.000000
mean   17377.229866     11.308399  ...  2.296640e+04     311.649606
std    13165.315011     43.443451  ...  7.498136e+04    2615.554211
min        1.000000      0.000000  ...  0.000000e+00       0.000000
25%     4389.250000      1.000000  ...  2.450000e+02       0.000000
50%    15135.000000      1.000000  ...  1.679500e+03       2.000000
75%    31146.500000     12.000000  ...  1.037900e+04      23.000000
max    37916.000000   1818.000000  ...  1.456378e+06  106895.000000

[8 rows x 8 columns]
>>> animelist.describe(include='O')
              title title_english  ... opening_theme ending_theme
count         14478          5724  ...         14478        14478
unique        14477          5606  ...          4328         5458
top     Hinamatsuri    Cyborg 009  ...            []           []
freq              2             4  ...          9784         8807

[4 rows x 22 columns]

Esses são alguns métodos que você pode adicionar a lista do que fazer quando tiver um dataset novo. Aumente a lista com os métodos que você achar necessário ou remova algum que não faz diferença pra você, mas sempre crie uma rotina dos primeiros passos com um dataset novo.

Referência:
Método read_csv()
Método sample()
Atributo shape
Método info()
Método describe()

domingo, 9 de agosto de 2020

Lendo tabelas HTML com pandas

Photo by Artem Sapegin on Unsplash

Um uso pouco conhecido da biblioteca pandas é a sua capacidade de ler tabelas de um site da web. Com pandas é fácil obter dados de uma tabela num site da web como a Wikipédia.
Nesse tutorial vamos obter dados de uma página na Wikipédia. Esses dados são das musicas de Avril Lavgine que foram utilizadas em séries.

Como ler dados de uma tabela HTML com pandas

Primeiro vamos chamar o método read_html(). Esse método carrega todas as tabelas de um arquivo html. Esse arquivo pode estar na internet ou no seu computador.

>>> import pandas as pd
>>> url = 'https://pt.wikipedia.org/wiki/Discografia_de_Avril_Lavigne'
>>> tabelas = pd.read_html(url)
>>> len(tabelas)
27

Com o código acima carregamos todas as tabelas no objeto tabelas. Com isso já podemos procurar pela tabela que queremos. Podemos acessar cada tabela com um índice do objeto tabela. A tabela que contem uma lista com as músicas que foram usados em séries é a 16.

>>> tabelas[16]
          Ano  ...   Ref.
0   2002/2004  ...  [108]
1   2002/2004  ...  [108]
2   2002/2004  ...  [108]
3        2003  ...  [108]
4        2003  ...  [108]
5        2003  ...  [108]
6        2003  ...  [108]
7        2003  ...  [108]
8        2004  ...  [108]
9        2004  ...  [108]
10       2005  ...  [108]
11       2005  ...  [108]
12  2007/2008  ...  [108]
13  2007/2008  ...  [108]
14  2007/2008  ...  [108]
15  2007/2008  ...  [108]
16  2007/2008  ...  [108]
17  2007/2008  ...  [108]
18  2007/2008  ...  [108]
19  2007/2008  ...  [108]
20       2008  ...  [108]
21       2008  ...  [108]
22       2008  ...  [108]
23       2008  ...  [108]
24  2008/2009  ...  [108]
25  2008/2009  ...  [108]
26       2009  ...  [108]
27       2009  ...  [108]

[28 rows x 5 columns]

Procurar por índice pode ser uma tarefa trabalhosa, especialmente se a pagina tiver muitas tabelas. Um jeito de encurtar a busca é carregar apenas a tabela que queremos. Podemos fazer isso identificando a tabela que nos interessa de algum modo. No exemplo abaixo vamos identificar a tabela pelo conteúdo da tag <caption>.

>>> url2 = 'https://en.wikipedia.org/wiki/The_Beatles_discography'
>>> beatles = pd.read_html(url2, match='List of studio albums', na_values='-')
>>> beatles
[                                                Title  ...                                     Certifications
                                                Title  ...                                     Certifications
0                                    Please Please Me  ...  BPI: Gold[10] ARIA: Gold[11] MC: Gold[12] RIAA...
1                                 With the Beatles[B]  ...  BPI: Gold[10] ARIA: Gold[11] BVMI: Gold[14] MC...
2                          Introducing... The Beatles  ...                                 RIAA: Platinum[13]
3                                   Meet the Beatles!  ...             MC: Platinum[12] RIAA: 5× Platinum[13]
4                                     Twist and Shout  ...                                MC: 3× Platinum[12]
5                           The Beatles' Second Album  ...             MC: Platinum[12] RIAA: 2× Platinum[13]
6                        The Beatles' Long Tall Sally  ...                                       MC: Gold[12]
7                                  A Hard Day's Night  ...             MC: Platinum[12] RIAA: 4× Platinum[13]
8                                  A Hard Day's Night  ...                   BPI: Platinum[10] ARIA: Gold[11]
9                                       Something New  ...                 MC: Gold[12] RIAA: 2× Platinum[13]
10                                   Beatles for Sale  ...  BPI: Gold[10] ARIA: Gold[11] MC: Gold[12] RIAA...
11                                        Beatles '65  ...             MC: Platinum[12] RIAA: 3× Platinum[13]
12                                         Beatles VI  ...                    MC: Gold[12] RIAA: Platinum[13]
13                                              Help!  ...                   BPI: Platinum[10] ARIA: Gold[11]
14                                              Help!  ...          MC: 2× Platinum[12] RIAA: 3× Platinum[13]
15                                        Rubber Soul  ...  BPI: Platinum[10] ARIA: Platinum[11] BVMI: Gol...
16                                        Rubber Soul  ...          MC: 2× Platinum[12] RIAA: 6× Platinum[13]
17                                Yesterday and Today  ...             MC: Platinum[12] RIAA: 2× Platinum[13]
18                                           Revolver  ...            BPI: 2× Platinum[10] ARIA: Platinum[11]
19                                           Revolver  ...          MC: 2× Platinum[12] RIAA: 5× Platinum[13]
20              Sgt. Pepper's Lonely Hearts Club Band  ...  BPI: 17× Platinum[10] ARIA: 4× Platinum[11] BV...
21                               Magical Mystery Tour  ...  BPI: Platinum[10] ARIA: Platinum[11] MC: 4× Pl...
22                    The Beatles ("The White Album")  ...  BPI: 2× Platinum[10] ARIA: 2× Platinum[11] MC:...
23                                Yellow Submarine[D]  ...      BPI: Gold[10] MC: Gold[12] RIAA: Platinum[13]
24                                         Abbey Road  ...  BPI: 3× Platinum[10] ARIA: 3× Platinum[11] BVM...
25                                          Let It Be  ...  BPI: Platinum[10] ARIA: Platinum[11] MC: 3× Pl...
26  "—" denotes that the recording did not chart o...  ...  "—" denotes that the recording did not chart o...

[27 rows x 10 columns]]

O parâmetro match especifica que queremos todas as tabelas que tenha a string que passamos para o parâmetro. Nessa pagina apenas uma tabela tinha a string, se tivesse mais elas seriam carregadas também. Outro jeito de especificar uma tabela é pelos atributos das tags HTML. Podemos procurar por atributo e valor do atributo. Por exemplo, se quiséssemos uma tabela cujo valor do atributo id seja tabela1, passaríamos o dicionario {'id':'tabela1'} para o parâmetro attrs. Podemos utilizar qualquer atributo e qualquer valor.

>>> tabela = pd.read_html(url, attrs={'class':'infobox_v2'})
>>> tabela
[   Discografia de Avril Lavigne Discografia de Avril Lavigne.1
0            Avril em Amsterdam             Avril em Amsterdam
1             Álbuns de estúdio                              6
2                Álbuns ao vivo                              4
3          Álbuns de compilação                              2
4               Álbuns de vídeo                              5
5           Extended plays (EP)                              4
6                       Singles                             25
7                       Lados B                             13
8               Vídeos musicais                             16
9             Álbuns de tributo                              1
10                 Vídeo single                              2
11                       Covers                             10
12            Álbuns de remixes                              2]

Nesse exemplo, carregamos todas as tabelas com o valor infobox_v2 atribuído ao atributo class. Nessa página, apenas uma tabela contem o valor infobox_v2 atribuído ao atributo class.

Como funciona o método read_html()

O método read_html() retorna uma lista com dataframes pandas. Para cada tabela encontrada na página um dataframe é criado.

Referência:
Método read_html()

Lendo o formato de dados JSON

Photo by Hello I'm Nik 🎞 on Unsplash

Um dos formatos mais comum, para a transferência de dados pela internet, é o JavaScrip Object Notation - JSON. Você pode estar pensando que esse formato de transferência de dados só poderia ser utilizado na linguagem de JavaScript, muito provável mente pelo nome JavaScrip, mas isso não é verdade. Muitas outras linguagens de programação fazem uso desse formato de transferência de dados, entre elas o python. O python já vem com um módulo para decodificar e codificar dados no formato JSON.

>>> import pandas as pd
>>> import json
>>> dados =  '{"nome":["Diana", "Fabiana", "Eveline"], "aniversario":[1998, 1991, 1995]}'
>>> pessoas = json.loads(dados)
>>> encoded = json.dumps(pessoas)
>>> encoded
'{"nome": ["Diana", "Fabiana", "Eveline"], "aniversario": [1998, 1991, 1995]}'

Trabalhando com JSON e pandas

Para o nosso primeiro exemplo vamos ler os dados no formato JSON e criar um dataframe pandas com esses dados. Você pode notar muita semelhança com o tipo de dados dicionário do python.

>>> pessoas = pd.read_json(encoded)
>>> pessoas
      nome  aniversario
0    Diana         1998
1  Fabiana         1991
2  Eveline         1995

Quando trabalhamos com dados JSON precisamos ter a certeza que esses dados estão no formato certo para que a biblioteca pandas possa carregá-lo corretamente. A biblioteca pandas tem suporte aos dados JSON nas seguintes orientações:

  • columns - (padrão) um mapeamento de nomes de colunas para uma lista de valores nas colunas.
  • records - uma lista de linhas. Cada linha é um dicionário que mapeia uma coluna para um valor.
  • split - Um mapeamento de columns para nomes de colunas, index para valores de índice e dados para uma lista de cada linha de dados (cada linha também é uma lista).
  • index - Um mapeamento do valor do index para uma linha. Uma linha é um dicionário que mapeia uma coluna para um valor.
  • values - uma lista de cada linha de dados (cada linha também é uma lista). Não inclui valores de coluna ou índice.
  • table - Um mapeamento de schema para o esquema DataFrame e dados para uma lista de dicionários.

Veja exemplos com diferentes orientações:

>>> records = pessoas.to_json(orient='records')
>>> records
'[{"nome":"Diana","aniversario":1998},{"nome":"Fabiana","aniversario":1991},{"nome":"Eveline","aniversario":1995}]'
>>> pd.read_json(records, orient='records')
      nome  aniversario
0    Diana         1998
1  Fabiana         1991
2  Eveline         1995

>>> split = pessoas.to_json(orient='split')
>>> split
'{"columns":["nome","aniversario"],"index":[0,1,2],"data":[["Diana",1998],["Fabiana",1991],["Eveline",1995]]}'
>>> pd.read_json(split, orient='split')
      nome  aniversario
0    Diana         1998
1  Fabiana         1991
2  Eveline         1995

O método loads() retorna um dicionário, por isso podemos ler os dados de apenas uma colunas.

>>> pessoas = json.loads(dados)
>>> type(pessoas)
<class 'dict'>
>>> pessoas['nome']
['Diana', 'Fabiana', 'Eveline']

Em algumas situações, pode ser mais fácil trabalhar com dicionários do que com JSON.

Referência:
Módulo JSON
Método read_json()
Método to_json()

Banco de dados com pandas

Imagem de CopyrightFreePictures por Pixabay

Já falamos algumas vezes que a biblioteca pandas é ótima para trabalhar com dados estruturados ou tabulares. É comum que grandes empresas usem bancos de dados para guardar dados tabulares ou estruturados. Nesse tutorial, vamos aprender a inserir e ler dados de um banco dados.
Vamos utilizar o SQLite. Este sistema de gerenciamento de banco de dados já está incluído no Python. Por isso não vamos precisar instalar nenhum módulo. Além do SQLite, podemos utilizar python para se conectar com os sistemas de gerenciamentos de banco de dados mais utilizados na atualidade. E podemos utilizar isso com o pandas.

Como utilizar o SQLite do python

Primeiro vamos criar um banco de dados e armazenar informações sobre pessoas aleatórias.

>>> import sqlite3
>>> db = sqlite3.connect('pessoas.db')
>>> cursor = db.cursor()
>>> cursor.execute(
... '''CREATE TABLE pessoas(id INTEGER PRIMARY KEY,
... p_nome TEXT, u_nome TEXT, aniversario INT)'''
... )
<sqlite3.Cursor object at 0x7f7993ce6650>
>>> cursor.execute(
... '''INSERT INTO pessoas VALUES(
... 0, 'Mario', 'Perreira', 1923)'''
... )
<sqlite3.Cursor object at 0x7f7993ce6650>
>>> cursor.execute(
... '''INSERT INTO pessoas VALUES(
... 1, 'Diana', 'Cruz', 1992)'''
... )
<sqlite3.Cursor object at 0x7f7993ce6650>
>>> db.commit()

Agora que já temos o nosso banco de dados vamos passar os dados desse banco de dados para um dataframe pandas. Para ler uma tabela vamos precisar usar o módulo SQLAlchemy. Esse módulo nós ajuda simplificando o processo de obtenção dos dados. O módulo SQLAlchemy não vem instalado com o python mas você pode instalar com o pip: pip install sqlalchemy.

>>> import pandas as pd
>>> import sqlalchemy as sa
>>> engine = sa.create_engine(
... 'sqlite:///pessoas.db', echo=True
... )
>>> conexao_sa = engine.connect()
>>> pessoas = pd.read_sql_table(
... 'pessoas', conexao_sa, index_col='id'
... )
>>> pessoas
   p_nome    u_nome  aniversario
id                              
0   Mario  Perreira         1923
1   Diana      Cruz         1992

Você pode selecionar os dados que quer ler com um consulta SQL. A consulta pode ser feita usando uma conexão SQLite ou SQLAlchemy. Nesse exemplo vamos usar a conexão SQLite do primeiro exemplo:

>>> nome_aniversario = pd.read_sql(sql, db)
>>> nome_aniversario
  p_nome  aniversario
0  Mario         1923
1  Diana         1992

Como funciona...

Nos exemplos desse tutorial, fizemos uso do módulo SQLAlchemy. Essa biblioteca faz a conexão entre o banco de dados SQL. SQLAlchemy pode criar uma conexão com a maioria dos bancos de dados SQL. Com essa conexão podemos criar dataframes a partir de tabelas. E ainda podemos criar um dataframe a partir de uma consulta SQL.

Referência:
Módulo SQLite3
Módulo SQLAlchemy

sexta-feira, 7 de agosto de 2020

Arquivos ZIP com pandas

Imagem de Alexas_Fotos por Pixabay

Já vimos nos tutoriais passados, que os arquivos csv são muito comuns para a criação de datasets. A principal característica dos arquivos csv é que eles são texto puro, sem formatação. Por isso eles podem ficar com um tamanho muito grande. Para tentar resolver esse problema os arquivos csv podem ser compactados. Nesse tutorial vamos aprender a carregar um arquivo csv compactado num arquivo ZIP.
O arquivo csv que vamos utilizar é o único arquivo dentro do arquivo ZIP. Você pode conseguir um arquivo semelhante compactando o arquivo filmes.csv. Nesse tutorial também vamos trabalhar com arquivos ZIP, com vários arquivos csv compactados.
Os arquivos que vamos usar nesse tutorial podem ser baixados gratuitamente aqui.

Como ler arquivos csv compactados

Vamos começar lendo um único arquivo csv compactado. Podemos fazer isso com o método read_csv(). A diferença é a extensão do arquivo que será zip e não csv.

>>> import pandas as pd
>>> animelist = pd.read_csv('AnimeList.zip')
>>> animelist
       anime_id  ...                                       ending_theme
0         11013  ...  ['#1: "Nirvana" by MUCC (eps 1, 11-12)', '#2: ...
1          2104  ...  ['#1: "Ashita e no Hikari (?????)" by Asuka Hi...
2          5262  ...  ['#1: "Rottara Rottara (???? ????)" by Buono! ...
3           721  ...  ['"Watashi No Ai Wa Chiisaikeredo" by Ritsuko ...
4         12365  ...  ['#1: "Pride on Everyday" by Sphere (eps 1-13)...
...         ...  ...                                                ...
14473     26089  ...                                                 []
14474     21525  ...                                                 []
14475     37897  ...                                                 []
14476     34193  ...                                                 []
14477     37908  ...                                                 []

[14478 rows x 31 columns]

Com arquivos compactados, contendo mais de um arquivo csv, a leitura desse arquivo é um pouco mais complicada, comparado com o exemplo anterior. Utilizando o método read_csv() não podemos especificar qual arquivo queremos ler dentro de um arquivo ZIP, mas podemos utilizar o módulo zipfile, que é uma biblioteca padrão do Python, para fazer isso.
Nesse exemplo vamos utilizar um arquivo zip contento mais de um arquivo csv. Você pode usar qualquer arquivo zip contendo arquivos csv.

>>> import pandas as pd
>>> import zipfile
>>> arq_zip = zipfile.ZipFile('dataset.zip')
>>> print('\n'.join(arq_zip.namelist()))
filmes.csv
anime_cleaned.csv
anime_filtered.csv
AnimeList.csv
>>> animeslist = pd.read_csv(arq_zip.open('AnimeList.csv'))
>>> animeslist
       anime_id  ...                                       ending_theme
0         11013  ...  ['#1: "Nirvana" by MUCC (eps 1, 11-12)', '#2: ...
1          2104  ...  ['#1: "Ashita e no Hikari (?????)" by Asuka Hi...
2          5262  ...  ['#1: "Rottara Rottara (???? ????)" by Buono! ...
3           721  ...  ['"Watashi No Ai Wa Chiisaikeredo" by Ritsuko ...
4         12365  ...  ['#1: "Pride on Everyday" by Sphere (eps 1-13)...
...         ...  ...                                                ...
14473     26089  ...                                                 []
14474     21525  ...                                                 []
14475     37897  ...                                                 []
14476     34193  ...                                                 []
14477     37908  ...                                                 []

[14478 rows x 31 columns]

Você pode trabalhar com arquivos compactados do tipo GZIP, XZ e BZ2. O método read_csv() aceita esses tipos de compressão.

Referência:
Método read_csv()
Método ZipFile()

Como ler e criar arquivos do Excel com pandas

Imagem de Esa Riutta por Pixabay

O arquivo CSV é muito comum e utilizado, mas se compararmos esse arquivo com o gigante da Microsoft, o arquivo do Excel, não parece ser grande coisa. Em muitas pesquisas de consultoria, os resultados apontam que o Excel é uma das ferramentas mais críticas em muitas empresas. O Excel é muito utilizado nas empresas para a tomada de muitas decisões importantes.
E por isso a biblioteca pandas fornece métodos para poder manipular esses arquivos. Nesse tutorial vamos aprender como criar e ler arquivos do Excel com a biblioteca pandas.
Antes de continuarmos vamos precisar instalar os pacotes xlwt e openpyxl. Esses pacotes são necessários para podermos exportar o nosso dataframe para um arquivo xls e xlsx. Utilize o pip para instalar os dois pacotes: pip install openpyxl xlwt.

Como ler e criar arquivos do Excel com pandas

O método que vamos utilizar, para criar um arquivo do excel, é o to_excel(). O que precisamos fazer é criar um dataframe e chamar esse método. Veja um exemplo:

>>> import pandas as pd
>>> nome = {'nome':['Fabiana', 'Diana', 'Amanda'],
... 'u_nome':['Ferreira', 'Lima', 'Saturno']}
>>> dataframe = pd.DataFrame(nome)
>>> dataframe.to_excel('dataframe.xls')
>>> dataframe.to_excel('dataframe.xlsx')

Abrindo o arquivo, que acabamos de criar, o resultado deve ser igual a este:

Para ler o arquivo que criamos, e qualquer outro feito no Excel, utilizamos o método read_excel(). Esse método precisa do complemento xlrd. Para baixo use o pip: pip install xlrd.

>>> import pandas as pd
>>> dataframe = pd.read_excel('dataframe.xls')
>>> dataframe
   Unnamed: 0     nome    u_nome
0           0  Fabiana  Ferreira
1           1    Diana      Lima
2           2   Amanda   Saturno

Como o arquivo já tem uma coluna de índice, podemos especificar isso para o método read_excel(), para evitar dados duplicados. Assim não teremos duas colunas de índice.

>>> dataframe = pd.read_excel('dataframe.xlsx', index_col=0)
>>> dataframe
      nome    u_nome
0  Fabiana  Ferreira
1    Diana      Lima
2   Amanda   Saturno

Com esses exemplos aprendemos que podemos ler e criar arquivos do Excel com a biblioteca pandas. Com a instalação de poucos pacotes já podemos manipular o tipo de arquivo mais utilizados pelas empresas.

Referência:
Método DataFrame()
Método to_excel()
Método read_excel()

quinta-feira, 6 de agosto de 2020

Lendo arquivo csv enorme com pandas

Imagem de Tania Dimas por Pixabay

A biblioteca pandas precisa que o computador tenha memoria disponível suficiente para poder funcionar corretamente. Todos os dataframes são alocados na memoria antes de podermos fazer qualquer operação com esses dados. Se você precisar ler os dados de um dataset muito grande, a biblioteca pandas fornece algumas opções. Caso o seu arquivo possa ser processado em partes, você pode ler algumas partes e depois processa-las. Se no seu dispositivo tiver memoria suficiente você pode carregar o arquivo inteiro. Podemos usar algumas dicas para diminuir o tamanho do arquivo.
O recomendado é que o seu computador tenha de três a dez vezes a quantidade de memoria do arquivo que você está trabalhando. Essa memoria extra é usada para manipular esses dados.

Como ler arquivo csv muito grande

Nesse tutorial vamos ler o conjunto o dados filmes.csv. Esse dataset cabe na memória de qualquer computador da atualidade, mas para fins didáticos vamos fazer de conta que não existe memória suficiente. E quando tentamos carregar esse dataset na memória recebemos um erro de falta de memória.
Quando lidamos com arquivos grandes que nossos computadores não tenham memória suficiente precisamos definir o total de memória que o arquivo inteiro vai ocupar. Para essa tarefa vamos usar o parâmetro nrows. Com esse parâmetro definimos a quantidade de linhas que serão carregados na memória.

>>> import pandas as pd
>>> filmes = pd.read_csv('filmes.csv', nrows=1000)
>>> filmes
     indice  codigo_obra  ...     cnpj_requerente data_exibicao
0         0      15639.0  ...  00.568.159/0001-07     06/jul/12
1         1          NaN  ...  03.599.148/0001-82     13/jul/04
2         2      26453.0  ...  02.341.697/0001-90    26/09/2007
3         3          NaN  ...  27.654.722/0001-16    16/12/2002
4         4       4806.0  ...  00.979.601/0001-98     15/jan/03
..      ...          ...  ...                 ...           ...
995     995   18001845.0  ...  00.979.601/0001-98    09/05/2018
996     996   17004586.0  ...  03.599.148/0001-82     19/jul/18
997     997   18002435.0  ...  27.654.722/0001-16     08/jun/18
998     998   17005733.0  ...  06.236.625/0001-33     05/jun/18
999     999   18002628.0  ...  08.346.733/0001-94     04/jul/18

[1000 rows x 9 columns]

Uma coisa importante é saber o quanto de memória um dataframe esta utilizando, e para isso temos o método info(). Esse método fornece algumas informações sobre o dataframe, incluindo a quantidade de memória utilizada.

>>> filmes.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 9 columns):
 #   Column                   Non-Null Count  Dtype
---  ------                   --------------  -----
 0   indice                   1000 non-null   int64
 1   codigo_obra              997 non-null    float64
 2   titulo_original          1000 non-null   object
 3   titulo_brasil            1000 non-null   object
 4   ano_producao             999 non-null    float64
 5   diretor                  1000 non-null   object
 6   razao_social_requerente  1000 non-null   object
 7   cnpj_requerente          1000 non-null   object
 8   data_exibicao            1000 non-null   object
dtypes: float64(2), int64(1), object(6)
memory usage: 46.9+ KB

Além das linhas podemos definir quais colunas queremos carregar na memória com o parâmetro usecols.

>>> col = [
... 'diretor',
... 'titulo_original'
... ]
>>> filmes = pd.read_csv('filmes.csv', nrows=1000, usecols=col)
>>> filmes.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 2 columns):
 #   Column           Non-Null Count  Dtype
---  ------           --------------  -----
 0   titulo_original  1000 non-null   object
 1   diretor          1000 non-null   object
dtypes: object(2)
memory usage: 7.9+ KB

Selecionando linhas e colunas, conseguimos reduzir o tamanho do dataframe. Com isso podemos reduzir o tamanho de qualquer dataframe.

Referência:
Método read_csv()
Método info()