我需要创建布尔/二进制数组,其中的行表示给定范围内每个数字的二进制形式。每列保存给定位位置的值。范围由位宽和二进制编码方案确定。然后我需要计算列中与前一个单元格不匹配的单元格数。
我相信计数过程只是对数组进行异或运算,并将其自身向下移动一行。 XOR结果中每列的总和是我的转换计数。
我需要为[有符号,无符号]值的每个组合执行此操作,这些值编码为[十六进制,八进制,十进制]。编码方案与可用位之间的不匹配导致无法使用的位 e.g。 4位无符号八进制数组仍然只有8行。但是,如果它已经签名,则第4位用于签名,阵列是完整的16行。
最终目标是针对各种位宽,编码和符号的使用,为每个位位置处的转换数创建标记的汇总n-gram。例如1的摘要n-gram将是{3-bit,octal,unsigned,[1,3,7]}。例3的摘要n-gram是{4-bit,octal,signed,[1,2,6,13]}。例4是{4位,十六进制,有符号,[1,2,6,13]}。
示例:
1) 8x3所有可能的3位无符号八进制值的二进制数组:
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
2) 8x4所有可能的4位无符号八进制值的二进制数组:
与#1相同,除了最后一列全部为零
3) 16x4所有可能的4位有符号八进制值的二进制数组:
注意:可以重复计算零(-0和+0)
1 1 1 1
1 1 1 0
1 1 0 1
1 1 0 0
1 0 1 1
1 0 1 0
1 0 0 1
1 0 0 0
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
4) 16x4所有可能的4位有符号十六进制值的二进制数组:
与#3相同
答案 0 :(得分:2)
您可以使用np.unpackbits
,例如
np.unpackbits(np.arange(8).astype(np.uint8)[:, None], axis = 1)
输出:
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 1, 1, 1]], dtype=uint8)
切掉不需要的零:
np.unpackbits(np.arange(8).astype(np.uint8)[:, None], axis = 1)[:, -3:]
结果:
array([[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 1, 1],
[1, 0, 0],
[1, 0, 1],
[1, 1, 0],
[1, 1, 1]], dtype=uint8)
将模数用于签名值:
np.unpackbits((np.arange(-4, 4)%8).astype(np.uint8)[:, None], axis = 1)[:, -3:]
或者查看从签名到无签名的转换:
np.unpackbits(np.arange(-4, 4).astype(np.int8).view(np.uint8)[:, None], axis = 1)[:, -3:]
结果:
array([[1, 0, 0],
[1, 0, 1],
[1, 1, 0],
[1, 1, 1],
[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 1, 1]], dtype=uint8)
过渡计数:
x = np.unpackbits(np.arange(-4, 4).astype(np.int8).view(np.uint8)[:, None], axis = 1)[:, -3:]
np.abs(np.diff(x.view(np.int8), axis=0)).sum(axis=1)
结果:
array([1, 2, 1, 3, 1, 2, 1])
或者使用你的xor方法:
(x[1:]^x[:-1]).sum(axis=1)
结果:
array([1, 2, 1, 3, 1, 2, 1], dtype=uint64)