Оценка количества строк в файле - несоответствие между размером файла и размером всех строк

У меня есть несколько сотен файлов, каждый размером от 10 МБ до нескольких ГБ, и я хотел бы оценить количество строк (т. Е. Точное количество не требуется). Каждая строка очень регулярна, например что-то вроде 4 длинных целых и 5 двойных поплавков.

Я пытался найти средний размер первого AVE_OVER строк в файле, а затем используйте его для оценки общего количества строк:

nums = sum(1 for line in open(files[0]))
print "Number of lines = ", nums

AVE_OVER = 10
lineSize = 0.0
count = 0
for line in open(files[0]):
    lineSize += sys.getsizeof(line)
    count += 1
    if( count >= AVE_OVER ): break

lineSize /= count
fileSize = os.path.getsize(files[0])
numLines = fileSize/lineSize
print "Estimated number of lines = ", numLines

Оценка была далеко:

> Number of lines =  505235
> Estimated number of lines =  324604.165863

Поэтому я попытался подсчитать общий размер всех строк в файле по сравнению с sys измеренный размер:

fileSize = os.path.getsize(files[0])
totalLineSize = 0.0
for line in open(files[0]):
totalLineSize += sys.getsizeof(line)

print "File size = %.3e" % (fileSize)
print "Total Line Size = %.3e" % (totalLineSize)

Но опять же они не соответствуют друг другу!

> File size = 3.366e+07
> Total Line Size = 5.236e+07

Почему сумма размеров каждой строки намного больше, чем фактический общий размер файла? Как я могу исправить это?


Редактировать: алгоритм, который я закончил (версия 2.0); Благодаря @JFSebastian

def estimateLines(files):
    """ Estimate the number of lines in the given file(s) """

    if( not np.iterable(files) ): files = [files]
    LEARN_SIZE = 8192

    # Get total size of all files                                                                                                                                                                   
    numLines = sum( os.path.getsize(fil) for fil in files )

    with open(files[0], 'rb') as file:
         buf = file.read(LEARN_SIZE)
         numLines /= (len(buf) // buf.count(b'\n'))

    return numLines

2 ответа

Решение

Чтобы оценить количество строк в файле:

def line_size_hint(filename, learn_size=1<<13):
    with open(filename, 'rb') as file:
        buf = file.read(learn_size)
        return len(buf) // buf.count(b'\n')

number_of_lines_approx = os.path.getsize(filename) // line_size_hint(filename)

Чтобы найти точное количество строк, вы можете использовать wc-l.py сценарий:

#!/usr/bin/env python
import sys
from functools import partial

print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), '')))

sys.getsizeof это единственная причина проблем здесь. Он дает произвольные зависящие от реализации размеры объектов и не должен использоваться вообще, за исключением очень редких случаев.

Просто откройте файл как двоичный файл и получите фактическую длину строк, используя len,

Другие вопросы по тегам