title: Fast / built-in bit-manipulation in Python/numpy?
body: <p>I'm using an external library that outputs a numpy array w/ data type ">u2" (big-endian, unsigned, 2-byte / 16-bit). In my case, only 10-bits are effective (the output is from a hardware device that actually outputs <strong>little-endian</strong>). For example:</p>
  
  <p><code>65283</code> is the max value, corresponding to <code>bin(65283)=0b1111111100000011</code> as the direct python output, or <code>00001111111111</code> if it were little-endian.</p>
  
  <p>I would like to map the range <code>0-65283</code> output from the library to the range <code>0-1023</code> that makes sense from the 10-bit hardware capability. How do I do this?</p>
  
  <p>I've tried the following:</p>
  
  <pre><code>&gt;&gt;&gt;import numpy as np
  
  &gt;&gt;&gt;arr=np.array([65283, 6528, 652, 65, 6], dtype="&gt;u2")
  &gt;&gt;&gt;print arr/64  # same as arr/2**6 and arr &gt;&gt; 6
  [1020  102   10    1    0]
  &gt;&gt;&gt;print arr.byteswap()
  [ 1023 32793 35842 16640  1536]
  </code></pre>
  
  <p>But this does not give the desired result. What I've found is that the <code>bin()</code> function outputs in big-endian format (in the case of this numpy array), but with padded zeros omitted. For example, 65283 has all 16-bits represented, but <code>bin(6528)=0b1100110000000</code> (missing 3 zeros in the middle).</p>
  
  <p>To fix this (and return a 10-bit little-endian number), I can get the binary form of 6528, add 3 zeros in the middle, and do a byte-swap. But 1) this is super tedious (done per element) and 2) the zero-padding is inconsistent (e.g. 652 requires 6 more zeros).</p>
  
  <p>Is there a built-in way to do this? It looks like the <code>struct</code> module (w/ <code>pack</code> and or <code>unpack</code>) might help, but it's Greek to me right now. Any help would be appreciated!</p>
  
  <p><strong>EDIT</strong>:</p>
  
  <p>Believe I've found the culprit. My example above (taking an actual value from the camera/library of 65238 and assuming semi-arbitrary additional values, which just have the right-most digit removed, obviously) wouldn't happen! e.g. 6528 requires a 1 in the least-significant byte (<code>00011001**1**0000000</code>) and that would never happen (only 10-bits are effective).</p>
  
  <p>Upon further inspection, a simple <code>arr.byteswap()</code> in my code (where <code>arr</code> has legitimate values) works. e.g.:</p>
  
  <pre><code>&gt;&gt;&gt;arr=np.array([12288, 13312, 12800, 12032, 13312, 13824, 65283, 0, 7936], dtype="&gt;u2")
  &gt;&gt;&gt;arr.byteswap()
  array([  48,   52,   50,   47,   52,   54, 1023,    0,   31], dtype=uint16)
  </code></pre>
  
  <p>I had never actually tried that in my code, only in this made-up example. Sorry for the confusion. But hopefully it may help someone else stumbling around this problem (especially if you use Basler cameras!), which turned out to be trivial I guess...</p>