Найти - Пользователи
Полная версия: Байт как индекс
Начало » Python для новичков » Байт как индекс
1
Dimedrol777
Только начал учить Питон. Задача касается информационной энтропии.
Есть произвольный файл, каждый прочитанный из него байт нужно использовать как индекс массива.
за первые пол-часа изучения Питона пошел извращенским путем: считая, что символы строкового объекта, прочитанного из файла соответствуют ASC II представлению, вызываю ord(), который и дает мне ASC II код строки, длиной в один символ. Скорость работы, как я понимаю, паршивая.
import math  

def cEntropy(p):
ent = 0
for i in range(CH_MAX):
if p[i] != 0:
ent = ent + p[i] * math.log(p[i]) / math.log(2)
ent = -ent
return ent

CH_MAX = 256
codes = [0]*256
p = [0]*256
fileLength = 0
m = 0
fName = raw_input('Enter filename: ')
f = open(fName, 'rb')
while 1:
nel = (f.read(1)) #Читаем очередной байт
if nel == "":
break
t = ord(nel) #Вот тут само извращение
codes[t] = codes[t] + 1
fileLength = fileLength + 1
if fileLenth % 1000000 == 0:
print '*'
for i in range(CH_MAX):
p[i] = float(codes[i]) / fileLength
if codes[i] != 0:
m = m + 1
entropy = cEntropy(p)
print 'File size is:', fileLength, 'bytes'
print 'This file entropy is:' , entropy, 'bits/mes'
print 'Dimension of primary alphabet:', m
f.close()
Прошу ламером не называть :)))
Dimka665
import array

и вместо range, xrange.
Dimka665
а вообще чудно пишешь)
например, твою функцию cEntropy
def cEntropy(p):
ent = 0
for i in range(CH_MAX):
if p[i] != 0:
ent = ent + p[i] * math.log(p[i]) / math.log(2)
ent = -ent
return ent
можно записать так:
def cEntropy(p):
ent = 0
for i in p:
if i:
ent += i * math.log(i) / math.log(2)
return -ent
или так)))
-sum((i * math.log(i) / math.log(2) for i in p))
Dimka665
еще)))

math.log(i) / math.log(2) == math.log(i, 2)
и нечего по 1 байту читать! читай весь файл или большими кусками.
Dimedrol777
Скажу коротко: СПАСИБО !
Т.е., вы советуете использовать array.fromfile(f, n)?
Сделал так:
import array, math

def cEntropy(p):
ent = 0
n_chars = len(p)
for i in xrange(n_chars):
if p[i] != 0:
ent += p[i] * math.log(p[i]) / math.log(2)
return -ent

CH_MAX = 256
codes = [0]*256
p = [0]*256
fileLength = 0
m = 0
fName = raw_input('Enter filename: ')
f = open(fName, 'rb')
while 1:
fblok = array.array('B')
fblok.fromstring(f.read(4000))
if not fblok:
break
arLen = len(fblok)
for i in xrange(arLen):
codes[fblok[i]] = codes[fblok[i]] + 1
fileLength = fileLength + 1
if fileLength % 1000000 == 0:
print '*'
n_chars = len(p)
for i in xrange(n_chars):
p[i] = float(codes[i]) / fileLength
if codes[i]:
m = m + 1
for i in xrange(n_chars):
if p[i] != 0:
print 'symbol = ', i, 'p = ', p[i]
entropy = cEntropy(p)
print 'File size is:', fileLength, 'bytes'
print 'This file entropy is:' , entropy, 'bits/mes'
print 'Dimension of primary alphabet:', m
f.close()
raw_input()
если написать так:
for i in p :
цикл не выполнится ни разу…
Dimedrol777
И самое важное, Питон программист ведь не обязан презирать язык Си ? :D :D :D
Dimka665
для начала можно не использовать array, читать файл целиком и
вместо

entropy = cEntropy(p)

написать

entropy = -sum((i * math.log(i, 2) for i in p))
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB