Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 20, 2009 14:42:42

Dimedrol777
От:
Зарегистрирован: 2009-02-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

Только начал учить Питон. Задача касается информационной энтропии.
Есть произвольный файл, каждый прочитанный из него байт нужно использовать как индекс массива.
за первые пол-часа изучения Питона пошел извращенским путем: считая, что символы строкового объекта, прочитанного из файла соответствуют 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()
Прошу ламером не называть :)))



Офлайн

#2 Фев. 20, 2009 15:02:51

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

import array

и вместо range, xrange.



Офлайн

#3 Фев. 20, 2009 15:12:16

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

а вообще чудно пишешь)
например, твою функцию 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))



Офлайн

#4 Фев. 20, 2009 15:21:25

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

еще)))

math.log(i) / math.log(2) == math.log(i, 2)
и нечего по 1 байту читать! читай весь файл или большими кусками.



Отредактировано (Фев. 20, 2009 15:25:06)

Офлайн

#5 Фев. 20, 2009 15:26:35

Dimedrol777
От:
Зарегистрирован: 2009-02-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

Скажу коротко: СПАСИБО !
Т.е., вы советуете использовать 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 :
цикл не выполнится ни разу…



Отредактировано (Фев. 20, 2009 16:45:44)

Офлайн

#6 Фев. 20, 2009 16:47:23

Dimedrol777
От:
Зарегистрирован: 2009-02-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

И самое важное, Питон программист ведь не обязан презирать язык Си ? :D :D :D



Отредактировано (Фев. 20, 2009 16:50:27)

Офлайн

#7 Фев. 22, 2009 12:31:51

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

Байт как индекс

для начала можно не использовать array, читать файл целиком и
вместо

entropy = cEntropy(p)

написать

entropy = -sum((i * math.log(i, 2) for i in p))



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version