Форум сайта python.su
Только начал учить Питон. Задача касается информационной энтропии.
Есть произвольный файл, каждый прочитанный из него байт нужно использовать как индекс массива.
за первые пол-часа изучения Питона пошел извращенским путем: считая, что символы строкового объекта, прочитанного из файла соответствуют 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()
Офлайн
import array
и вместо range, xrange.
Офлайн
а вообще чудно пишешь)
например, твою функцию 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))
Офлайн
еще)))
math.log(i) / math.log(2) == math.log(i, 2)
Отредактировано (Фев. 20, 2009 15:25:06)
Офлайн
Скажу коротко: СПАСИБО !
Т.е., вы советуете использовать 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()
Отредактировано (Фев. 20, 2009 16:45:44)
Офлайн
И самое важное, Питон программист ведь не обязан презирать язык Си ? :D :D :D
Отредактировано (Фев. 20, 2009 16:50:27)
Офлайн
для начала можно не использовать array, читать файл целиком и
вместо
entropy = cEntropy(p)
написать
entropy = -sum((i * math.log(i, 2) for i in p))
Офлайн