Utilisation de numpy.unpackbits
est plus rapide si fp
est un grand tableau NumPy :
(np.unpackbits(fp.astype('>i4').view('4,uint8'), axis=1).T.astype(bool))
astype('>i4')
convertit fp
dans un tableau d'ints 32 bits big-endian, puis view('4,uint8')
voit (ou, on pourrait peut-être dire, réinterprète) l'image 32 bits de l'utilisateur. comme quatre ints de 8 bits. Ceci est fait puisque unpackbits
s'attend à un tableau de ints 8 bits non signés. Le format big-endian est utilisé pour s'assurer que les bits les plus importants les bits les plus significatifs se trouvent à gauche, ce qui permet d'organiser les valeurs de la manière suivante np.unpackbits
retourne le bits dans l'ordre souhaité.
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()
Utilisation de np.unpackbits
est environ 72x plus rapide (sur ma machine) pour un tableau de taille 100. La vitesse augmente avec la longueur du tableau 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