有没有更好的(更有效和/或可读)的方法将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]]
答案 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