如何将字节列表转换为带符号的short列表

时间:2018-08-03 21:23:48

标签: python python-3.x numpy

我尝试过类似的事情:

    import array
    data = self._data.read(size)
    samples = array.array('h')
    it = iter(data)
    grouped_data = zip(it, it)
    for d in grouped_data:
        samples.append(d[0] | d[1] << 8)

    return samples

数据是一个列表[],其值在0到255之间。

我需要进行转换,以使其成为带符号的简短列表。

我尝试了一个带符号的short类型数组,但有时它会尝试插入比带符号的short类型“更大”的值,因为它不能处理数字应该为负的情况。

也许numpy在这里有帮助吗?

2 个答案:

答案 0 :(得分:3)

您在这里几乎肯定想要的是frombytes

>>> b = b'\1\2\3\4\xff\xff'
>>> a = array.array('h')
>>> a.frombytes(b)
>>> a
array('h', [513, 1027, -1])

或者,如果那是错误的字节序?

>>> a.byteswap()
>>> a
array('h', [258, 772, -1])

可以手动修复纠缠不清的数学运算,但是为什么要这么困难呢? (如果您因为自从上幼儿园以来就一直使用C进行编码,就已经本能地知道如何打来个混帐,那不是很难的方法,但是那样的话您就不会问这个问题了。) 1


但是,由于您提到了numpy,因此您可能根本不想使用array

>>> np.frombuffer(b, dtype=np.int16)
array([ 513, 1027,   -1], dtype=int16)

这与上面的操作完全相同,甚至存储也以字节为单位等效,但是现在您有了一个numpy数组而不是数组数组,而numpy数组更有用。


1。如果您感到好奇,那么思考它的最简单方法就是明确表示:要将无符号的int重新解释为(2的补码)有符号的int,只需将MSB重新解释为有符号的,而其他字节则不用理会。要将无符号字节重新解释为(2的补码)有符号字节,只需将0x100减去>=0x80即可。因此d[1]-256 if d[1]>128 else d[1]可以做到。不是最短或最有效的代码,但可能是最容易理解的代码。

答案 1 :(得分:0)

我刚刚发现可以使用

numpy.int16

所以我将代码转换为:

import array
data = self._data.read(size)
samples = []
it = iter(data)
grouped_data = zip(it, it)
for d in grouped_data:
    samples.append(numpy.int16(d[0] | d[1] << 8))

return samples