计算文件的信息量(信息论实验,cmd命令行运行)
程序(calcInfo.py)
import argparse
import numpy as np
def main():
(in_file_name,out_file_name, do_test) =parse_sys_args()
if(do_test): #执行测试
test_workflow()
else: #不测试,执行工作流
worklflow(in_file_name, out_file_name)
def worklflow(in_file_name,out_file_name): #工作流
x = read_input(in_file_name)
info = compute_info(x)
write_output(out_file_name,in_file_name,info,x.size)
def parse_sys_args(): #解析命令行参数
parser = argparse.ArgumentParser(description='calculate the average information content per byte of a file.')
parser.add_argument('fileIn', help='path of the input file',nargs='?')
parser.add_argument('fileOut', help='path of the Output file',nargs='?')
parser.add_argument("-t", "--test", help="Do Test", action="store_true")
args = parser.parse_args()
return (args.fileIn,args.fileOut,args.test)
def compute_info(x): #计算信息量
value=np.zeros(256)
for i in x:
value[i]=value[i]+1
p = value / x.size
p = np.where(p==0, 1, p)
self_info=-np.log2(p)
info= np.sum(p*self_info)
return info
def read_input(in_file_name):#读取文件成字节流
f = np.fromfile(in_file_name, dtype=np.uint8)
return f
def write_output(out_file_name, in_file_name, info, x_size): #将结果写出文件
fout = open(out_file_name, 'a')
fout.write('"'+in_file_name+'","'+str(x_size)+'","'+str(info)+'"\n')
fout.close()
def test_workflow(): #测试
# 测试1:生成字符数为512,数值全为1的矩阵。该信源只有一个符号出现概率为1,其他符号概率为0,所以信息量应为0 bit/byte。
x_len = 512
symbol = 1
x = np.full(x_len, symbol, dtype=np.uint8)
Info = compute_info(x)
print("test1 1: a 512 bytes message with P(x=1)=1 \n\texpecting=0.0 bit/byte, result="+str(Info)+' bit/byte')
#测试2:生成字符数为512,数值为0,0,1,1...,255,255的矩阵,文件中包含所有可能的256种字节符号,且出现概率相等。所以信息量应为:8 bit/byte。
y_len = 512
y = np.repeat(np.arange(256, dtype=np.uint8), y_len/256)
Info = compute_info(y)
print("test 2: a 512 bytes message with all P(x)=1/256 \n\texpecting=8.0 bit/byte, result="+str(Info)+' bit/byte')
#测试3:生成字符数为512的矩阵,文件中只包含2种字节符号0和1,其出现的概率都是1/2。信息量应为:1 bit/byte。
z_len = 512
symbol_1 = 0
symbol_2 = symbol_1 + 1
z = np.repeat(np.array([symbol_1, symbol_2]).astype(np.uint8), z_len/2)
Info = compute_info(z)
print("test 3: a 512 bytes message with P(x=0)=1/2,P(x=1)=1/2 \n\texpecting=1.0 bit/byte, result="+str(Info)+' bit/byte')
if __name__ == '__main__':
main()
运行说明
1.安装和初始化
程序为Python文件:calcInfo.py。下载保存至文件夹即可。
2.运行步骤
2.1 打开cmd
2.2 进入calcInfo.py所在的目录
2.3 输入
2.3.1:python calcInfo.py [fileIn] [fileOut] 【[fileIn]为待计算信息量的文件的路径,[fileOut]为存放输出结果的路径】
2.3.2:python calcInfo.py -t 【运行单元测试】(目前仅支持这两种输入方式)
2.4 输出
2.4.1 输入python calcInfo.py [fileIn] [fileOut],会将计算好的信息量写入到[fileOut]中,可打开[fileOut]查看计算结果。[fileOut]中新增的一行即为计算结果:第一个字符串为文件名;第二个字符串为文件大小,单位为B;第三个字符串为计算出的文件信息量,单位为bit/byte。
2.4.2 输入python calcInfo.py -t ,会在屏幕上显示测试结果。
2.5 举例
2.5.1:输入python calcInfo.py p1.jpg calcInfo.output.csv
打开calcInfo.output.csv,文件新增了一行计算结果。p1.jpg为输入的文件,27931为文件大小,单位为B,7.906689059264634为计算出的文件信息量,单位为bit/byte。
2.5.2:输入python calcInfo.py -t,屏幕上打印出了测试结果。
2.6 帮助
输入:python calcInfo.py -h 或 python calcInfo.py --help 查看帮助。