Pythonic方法将signed int32的列表转换为binary / boolean numpy数组

时间:2017-09-08 03:01:41

标签: python arrays numpy

有没有更好的(更有效和/或可读)的方法将signed int32转换为转置的binary / boolean numpy数组?

  

这个例子是一个简化。 fp可以有近1,000个元素

这是我到目前为止(使用Python 2.7):

fp = [-15707075, -284140225]
np.transpose(np.array([[b == '1' for b in list('{:32b}'.format(i & 0xffffffff))] for i in fp]))

结果:

[[ True  True]
 [ True  True]
 [ True  True]
 [ True False]
 [ True  True]
 [ True  True]
 [ True  True]
 [ True  True]
 [False False]
 [False False]
 [False False]
 [ True  True]
 [False False]
 [False False]
 [False False]
 [False False]
 [False False]
 [ True  True]
 [False False]
 [ True  True]
 [False  True]
 [ True  True]
 [False False]
 [False  True]
 [False False]
 [False False]
 [ True  True]
 [ True  True]
 [ True  True]
 [ True  True]
 [False  True]
 [ True  True]]

2 个答案:

答案 0 :(得分:3)

如果fp是一个较大的NumPy数组,则使用numpy.unpackbits会更快:

(np.unpackbits(fp.astype('>i4').view('4,uint8'), axis=1).T.astype(bool))

astype('>i4')fp转换为大端32位整数数组 view('4,uint8')个视图(或者,也许你可能会说重新解释)32位 整数为4个8位整数。这是因为unpackbits期望一个数组 无符号8位整数。 Big-endian格式用于确保最重要的格式 位在左侧 - 这将排列值,以便np.unpackbits返回 按所需顺序排列。

In [280]: fp = np.array([-15707075, -284140225])

In [281]: fp.astype('>i4').view('4,uint8')
Out[281]: 
array([[255,  16,  84,  61],
       [239,  16,  93,  63]], dtype=uint8)

In [282]: np.unpackbits(fp.astype('>i4').view('4,uint8'), axis=1)
Out[282]: 
array([[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1,
        0, 0, 0, 0, 1, 1, 1, 1, 0, 1],
       [1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1,
        0, 1, 0, 0, 1, 1, 1, 1, 1, 1]], dtype=uint8)
import numpy as np

fp = np.array([-15707075, -284140225])
expected = (np.transpose(np.array([[b == '1' for b in list('{:32b}'.format(i & 0xffffffff))] for i in fp])))

result = (np.unpackbits(fp.astype('>i4').view('4,uint8'), axis=1).T.astype(bool))

assert (expected == result).all()

对于100的数组,使用np.unpackbits(在我的机器上)快约72倍。速度 优势随着fp

的长度而增加
In [241]: fp = np.random.random(size=100).view('int32')

In [276]: %timeit expected = (np.transpose(np.array([[b == '1' for b in list('{:32b}'.format(i & 0xffffffff))] for i in fp])))
100 loops, best of 3: 2.22 ms per loop

In [277]: %timeit result = (np.unpackbits(fp.astype('>i4').view('4,uint8'), axis=1).T.astype(bool))
10000 loops, best of 3: 30.6 µs per loop

答案 1 :(得分:0)

不是很多更好,但更多Pythonic:

np.array([list('{:32b}'.format(i & 0xffffffff)) for i in fp]).astype(bool).T