Python: convert numpy array of signs to int and back
<p>I'm trying to convert from a numpy array of signs (i.e., a numpy array whose entries are either <code>1.</code> or <code>-1.</code>) to an integer and back through a binary representation. I have something that works, but it's not Pythonic, and I expect it'll be slow.</p>

<pre><code>def sign2int(s):
    s[s==-1.] = 0.
    bstr = ''
    for i in range(len(s)):
        bstr = bstr + str(int(s[i]))
    return int(bstr, 2)

def int2sign(i, m):
    bstr = bin(i)[2:].zfill(m)
    s = []
    for d in bstr:
        s.append(float(d))
    s = np.array(s)
    s[s==0.] = -1.
    return s
</code></pre>

<p>Then </p>

<pre><code>&gt;&gt;&gt; m = 4
&gt;&gt;&gt; s0 = np.array([1., -1., 1., 1.])
&gt;&gt;&gt; i = sign2int(s0)
&gt;&gt;&gt; print i
11
&gt;&gt;&gt; s = int2sign(i, m)
&gt;&gt;&gt; print s
[ 1. -1.  1.  1.]
</code></pre>

<p>I'm concerned about (1) the for loops in each and (2) having to build an intermediate representation as a string. </p>

<p>Ultimately, I will want something that works with a 2-d numpy array, too---e.g.,</p>

<pre><code>&gt;&gt;&gt; s = np.array([[1., -1., 1.], [1., 1., 1.]])
&gt;&gt;&gt; print sign2int(s)
[5, 7]
</code></pre>

<p>For 1d arrays you can use this one linear Numpythonic approach, using <code>np.packbits</code>:</p>

<pre><code>&gt;&gt;&gt; np.packbits(np.pad((s0+1).astype(bool).astype(int), (8-s0.size, 0), 'constant'))
array([11], dtype=uint8)
</code></pre>

<p>And for reversing:</p>

<pre><code>&gt;&gt;&gt; unpack = (np.unpackbits(np.array([11], dtype=np.uint8))[-4:]).astype(float)
&gt;&gt;&gt; unpack[unpack==0] = -1
&gt;&gt;&gt; unpack
array([ 1., -1.,  1.,  1.])
</code></pre>

<p>And for 2d array:</p>

<pre><code>&gt;&gt;&gt; x, y = s.shape
&gt;&gt;&gt; np.packbits(np.pad((s+1).astype(bool).astype(int), (8-y, 0), 'constant')[-2:])
array([5, 7], dtype=uint8)
</code></pre>

<p>And for reversing:</p>

<pre><code>&gt;&gt;&gt; unpack = (np.unpackbits(np.array([5, 7], dtype='uint8'))).astype(float).reshape(x, 8)[:,-y:]
&gt;&gt;&gt; unpack[unpack==0] = -1
&gt;&gt;&gt; unpack
array([[ 1., -1.,  1.],
       [ 1.,  1.,  1.]])
</code></pre>

python arrays numpy binary