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

walmes . walmeszeviani em gmail.com
Sexta Outubro 24 20:22:09 BRST 2014


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 -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
linux user number: 531218
==========================================================================
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://listas.inf.ufpr.br/pipermail/r-br/attachments/20141024/3d02f4ce/attachment.html>


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