Quiero leer algunos archivos bastante grandes (para ser precisos: el conjunto de datos de palabras de google ngram 1) y contar cuántas veces ocurre un personaje. Ahora escribí este script:Python lee un archivo enorme línea por línea con codificación UFT-8
import fileinput
files = ['../../datasets/googlebooks-eng-all-1gram-20090715-%i.csv' % value for value in range(0,9)]
charcounts = {}
lastfile = ''
for line in fileinput.input(files):
line = line.strip()
data = line.split('\t')
for character in list(data[0]):
if (not character in charcounts):
charcounts[character] = 0
charcounts[character] += int(data[1])
if (fileinput.filename() is not lastfile):
print(fileinput.filename())
lastfile = fileinput.filename()
if(fileinput.filelineno() % 100000 == 0):
print(fileinput.filelineno())
print(charcounts)
que funciona bien, hasta que alcanza aprox. línea de 700.000 del primer archivo, a continuación, obtener este error:
../../datasets/googlebooks-eng-all-1gram-20090715-0.csv
100000
200000
300000
400000
500000
600000
700000
Traceback (most recent call last):
File "charactercounter.py", line 5, in <module>
for line in fileinput.input(files):
File "C:\Python31\lib\fileinput.py", line 254, in __next__
line = self.readline()
File "C:\Python31\lib\fileinput.py", line 349, in readline
self._buffer = self._file.readlines(self._bufsize)
File "C:\Python31\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 7771: cha
racter maps to <undefined>
Para resolver este He buscado en la web un poco, y se acercó con este código:
import fileinput
files = ['../../datasets/googlebooks-eng-all-1gram-20090715-%i.csv' % value for value in range(0,9)]
charcounts = {}
lastfile = ''
for line in fileinput.input(files,False,'',0,'r',fileinput.hook_encoded('utf-8')):
line = line.strip()
data = line.split('\t')
for character in list(data[0]):
if (not character in charcounts):
charcounts[character] = 0
charcounts[character] += int(data[1])
if (fileinput.filename() is not lastfile):
print(fileinput.filename())
lastfile = fileinput.filename()
if(fileinput.filelineno() % 100000 == 0):
print(fileinput.filelineno())
print(charcounts)
pero el gancho ahora uso intenta leer todo el archivo de 990 MB en la memoria a la vez, lo que bloquea mi PC. ¿Alguien sabe cómo reescribir este código para que realmente funcione?
p.s: el código ni siquiera ha corrido hasta el final, por lo que ni siquiera sé si hace lo que tiene que hacer, pero para que eso suceda, primero tengo que solucionar este error.
Ah, y yo uso de Python 3.2
comparación de rendimiento de contar caracteres en Python, Cython, C, .. http://stackoverflow.com/questions/2522152/python-is-a-dictionary-slow-to-find-frequency-of- each-character/2525617 # 2525617 – jfs
Para la gente interesada, el resultado (se agregó un filtro para solo az e hizo todo en minúscula): {'a': 102037493781, 'c': 42883014812, 'b': 19831999435, 'e' : 160625131890, 'd': 49858005683, 'g': 23703400644, 'f': 32139997560, 'i': 97477105220, 'h': 63989934675, 'k': 7050807601, 'j': 2260108213, 'm': 32292575753 , 'l': 52782661506, 'o': 100366604971, 'n': 93886203967, 'q': 1622282068, 'p': 27264105140, 's': 85883631327, 'r': 80049264186, 'u': 35187497669, ' t ': 114609472329,' w ': 21891971718,' v ': 13296202464,' y ': 21467638892,' x ': 3007834707,' z ': 1333102460} – teuneboon