[R-br] Processar uma base de dados grande - ENEM 2012 - 6 milhões de registros - só 40 segundos

Elias T. Krainski eliaskrainski em yahoo.com.br
Domingo Outubro 26 10:18:52 BRST 2014


com fread() e' possivel ainda selecionar colunas. Para trazer as 
respostas a prova de matematica, o gabarito e o escore demorou 14 
segundos...

system.time(all <- fread("../dados/dados2012/DADOS/DADOS_ENEM_2012.csv", 
select=c(64, 73, 78)))
Read 5791065 rows and 3 (of 80) columns from 3.522 GB file in 00:00:12
    user  system elapsed
  10.874   0.898  14.126

On 26/10/14 12:23, Elias T. Krainski wrote:
> Walmes,
>
> Muito legal a dica de usar o shell para isso. O shell e' sempre mais 
> rapido que qualquer coisa!
>
> Sobre ler dados do ENEM, usando fread() do pacote 'data.table' demorou 
> 210 segundos no meu laptop para dados 2012 do ENEM. Eu nao gostei 
> muito do INEP ter disponibilizado o formato .csv. Anteriormente, dados 
> de 2010 por exemplo, usava-se o formato fixed width. Usando uma funcao 
> (descrita em 
> http://www.leg.ufpr.br/doku.php/disciplinas:ce223101:historico2010) 
> demorou 238 segundos para ler os dados de 2010 (4.6 milhoes de linhas) 
> e selecionar prova de matematica dos alunos do Parana.
>
> Essa funcao que usei para ler (e SELECIONAR linhas, colunas) fixed 
> width usa a mesma ideia que voce fez usando read.table(). A diferenca 
> e' que eu abro uma coneccao apenas e uso readLines(). O que voce fez 
> com read.table() e' ineficiente porque ao ler cada bloco e' feita uma 
> nova coneccao com o arquivo (via funcao scan()) e ao ler o i-e'simo 
> bloco a funcao scan() precisa percorrer todos os dados dos blocos 
> anteriores antes de comecar a ler. Assim, para ler os ultimos blocos 
> demora-se um tempo enorme percorrendo...
>
> Abs,
> Elias.
>
> On 25/10/14 00:22, walmes . wrote:
>> Saudações,
>>
>> Essa mensagem é apenas para compartilhar uma experiência que tive e 
>> considero que o problema aqui discutido não seja tão particular.
>>
>> Fui procurado por alguém que precisava processar um arquivo com 
>> resultados da prova do ENEM 2012 para aplicar teoria de resposta ao 
>> item. Precisava-se processar o arquivo original para chegar em um que 
>> tivesse apenas 5 das 80 colunas (notas para as competências sobre a 
>> redação) e somente às linhas que tivessem o conteúdo "P" (de 
>> presente) para a coluna "IN_STATUS_REDACAO". O arquivo é um csv, 
>> delimitador vírgula, aspas nas strings, 5791066 de linhas, 3.8 GB. 
>> Fiz o que me veio na cabeça de primeira: "dividir para conquistar". 
>> Lia porções de 30 mil linhas do arquivo (usando na read.table() o 
>> skip= e nrow=), separava as 5 colunas, mantinha só as linhas com 
>> registro P e escrevia para um arquivo com write.table(..., 
>> append=TRUE). Isso dentro de um for(). Na minha implementação, um 
>> tanto ingenua e corrida porque fiz enquanto era assistido a 
>> programar, quanto apliquei ao arquivo alvo levou 3h40. Esperava que 
>> fosse demorar mas não tanto. Minha máquina tem 16 GB de RAM. Sabendo 
>> que o bash do linux é muito eficiente para tarefas como operações em 
>> arquivos texto, eu fui buscar na internet como fazer o mesmo. 
>> Resultado é que tudo se resolveu com 37 segundos!!! É por isso que 
>> achei interessante compartilhar com a lista, inclusive para saber se 
>> alguem tem meios alternativos para solucionar o problema. Seguem os 
>> comandos que apliquei no terminal do Linux. Os dados fornecidos no 
>> exemplo são apenas as 10 mil primeiras linhas do arquivo original.
>>
>> ##-----------------------------------------------------------------------------
>> ## 0. Aquisição dos dados. Apenas 10000 registros dos 5791066 do arquivo
>> ## original.
>>
>> wget 
>> http://www.leg.ufpr.br/~walmes/data/DADOS_ENEM_2012_10millinhas.csv 
>> <http://www.leg.ufpr.br/%7Ewalmes/data/DADOS_ENEM_2012_10millinhas.csv> 
>> -O DADOS_ENEM_2012.csv
>> ls
>> wc -l DADOS_ENEM_2012.csv
>>
>> ##-----------------------------------------------------------------------------
>> ## 1. Filtrar só às colunas de interesse. Da 74 à 79. Na 74 tem-se os
>> ## valores P, F e outros.
>>
>> cut -d , -f 74-79 DADOS_ENEM_2012.csv > file.csv
>> head -10 file.csv
>> wc -l file.csv
>>
>> ##-----------------------------------------------------------------------------
>> ## 2. Manter só as linhas com ocorrência do P.
>>
>> grep "P" file.csv > fileP.csv
>> wc -l fileP.csv
>> head -10 fileP.csv
>>
>> ##-----------------------------------------------------------------------------
>> ## 3. Remover à colunas com P, ou seja, manter da 2 à 6.
>>
>> cut -d , -f 2-6 fileP.csv > file.csv
>> head -10 file.csv
>> wc -l file.csv
>>
>> ##-----------------------------------------------------------------------------
>> ## 4. Remover as aspas para salvar espaço em disco.
>>
>> sed 's/\"//g' file.csv > fileP.csv
>> head -10 fileP.csv
>>
>> ##-----------------------------------------------------------------------------
>> ## 5. Como contar o número de linhas repetidas. Gerar tabela de 
>> frequência dos
>> ## padrões de resposta. Economiza espaço e é a informação mínima
>> ## necessária para ajustar TRI. Remover o cabeçalho.
>>
>> sed 1d fileP.csv > file.csv
>> sort file.csv | uniq --count > fileP.csv
>> head -10 fileP.csv
>> tail -10 fileP.csv
>>
>> ##-----------------------------------------------------------------------------
>> ## 6. Eliminar espaços no ínicio e colocar uma vírgula entre a
>> ## frequência e o primeiro registro para que todos os campos sejam
>> ## separados por `,`.
>>
>> sed -e 's/^ *//;s/ /,/' fileP.csv > fileFreq.csv
>> head -10 fileFreq.csv
>> wc -l fileFreq.csv
>>
>> ##-----------------------------------------------------------------------------
>>
>> À disposição.
>> Walmes.
>>
>> ==========================================================================
>> Walmes Marques Zeviani
>> LEG (Laboratório de Estatística e Geoinformação, 25.450418 S, 
>> 49.231759 W)
>> Departamento de Estatística - Universidade Federal do Paraná
>> fone: (+55) 41 3361 3573
>> skype: walmeszeviani
>> homepage: http://www.leg.ufpr.br/~walmes 
>> <http://www.leg.ufpr.br/%7Ewalmes>
>> linux user number: 531218
>> ==========================================================================
>>
>>
>> _______________________________________________
>> R-br mailing list
>> R-br em listas.c3sl.ufpr.br
>> https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br
>> Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
>
>
>
> _______________________________________________
> R-br mailing list
> R-br em listas.c3sl.ufpr.br
> https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br
> Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.

-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://listas.inf.ufpr.br/pipermail/r-br/attachments/20141026/ff435c2a/attachment.html>


Mais detalhes sobre a lista de discussão R-br