title: slicing numpy arrays by combining indices and expression masks
body: <p>I've to analyse a (~20k vertices) 3D quad mesh and therefor need to decompose it into submeshes according to certain criteria. </p>
  
  <p>Given are </p>
  
  <ul>
  <li>an array of vertices (N 3-tuples of vertex coordinates, to be precise)</li>
  <li>quad faces referencing the sequence number of those vertices</li>
  <li>the reverse map of vertices to the sequential number of the (4) faces they belong to </li>
  </ul>
  
  <p>The basic criteria for the decomposition come in two flavors:</p>
  
  <ul>
  <li>as sequences of face- or vertex-indices</li>
  <li>or as expressions </li>
  </ul>
  
  <p>Those basic criteria need to be composed to yield the sets I need for my analyses.  </p>
  
  <p>It's easy to get an index list from an expression criterion; that's simply</p>
  
  <pre class="lang-py prettyprint-override"><code>numpy.where(mask)
  </code></pre>
  
  <p>What I don't know is how to efficiently get a mask from a given list of indices; the brute force approach in my SSCCE below (at (A))</p>
  
  <pre class="lang-py prettyprint-override"><code>boolean_mask_from_selected_face_indices = [
      i in selected_face_indices for i in range(faces.shape[0])
  ]
  </code></pre>
  
  <p>Works, but looks inefficient.</p>
  
  <p><strong>Thus I'd like to know a better way to get from index-based "masks" to boolean masking.</strong></p>
  
  <p>I reduced the SSCCE coords to two real dims and instead of IR² vecs I use complex numbers for representation - that flattens it a little; the topic is unaffected by that simplification.</p>
  
  <pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python2.7
  import numpy as np
  
  # ----------------------mocking the static data ----------------------72
  
  phi = np.pi/4.
  
  # corners of an axis-aligned square in the complex plane
  coords = np.array(
      [
          np.complex(np.cos(a), np.sin(a))
          for a in np.arange(phi, 8 * phi, 2 * phi)
      ])
  
  # appending cornes for a square turned left by pi/4 = 45 deg
  w = coords[0]
  coords = np.append(coords, coords * w)
  # print np.round(coords)
  
  # indices for both quads
  faces = np.arange(8).reshape(2, 4)
  
  # generating dummy duplicates
  faces = np.append(faces, faces, axis=0)
  print faces
  # which are to be excluded
  apriori_face_mask = [True, True, False, False]
  
  # reverse indexing
  vertex_faces = np.append(np.zeros(4, dtype=int), np.ones(4, dtype=int))
  # for the duplicates
  vertex_faces = np.append(vertex_faces, vertex_faces)
  
  # ---------------------------- runtime -------------------------------72
  
  # selecting vertices by certain criteria
  runtime_mask = (np.imag(coords) &gt; (float(1.) - np.finfo(float).eps))
  
  # selecting the corresponding face
  selected_face_indices = vertex_faces[np.where(runtime_mask)]
  
  # ################################################################
  # (A) this is what I'd like to improve
  # ################################################################
  boolean_mask_from_selected_face_indices = [
      i in selected_face_indices for i in range(faces.shape[0])
  ]
  # ################################################################
  
  # -----------------------------------------------------------------
  # (B) combining the two filters
  selected_faces = faces[
      np.logical_and(apriori_face_mask,
                     boolean_mask_from_selected_face_indices)
  ]
  # ----------------------------------------------------------------------
  
  assert(selected_faces.shape[0] == 1)
  
  try:
      import matplotlib.pyplot as plt
      res = coords[selected_faces.flat]
      plt.fill(np.real(res), np.imag(res), facecolor="r")
      plt.show()
  except ImportError as e:
      print("No matplotlib.pyplot; text result is:")
      print(selected_faces)
  </code></pre>
  
  <p>It may be important to state that for my work, I don't need to re-index faces; for my needs it's good enough  that only the face selection reflects the current working set, carrying along the whole load of vertices doesn't cost me anything. </p>
  
  <p>That has the implication that I also don't want to bother with any re-indexing and the related costs if that can be avoided.</p>
  
  <p>numpy version is 1.9.1
  platform is 64bit (Debian jessie amd64)</p>
  
  <p><strong>EDIT:</strong> 
  OK, this </p>
  
  <pre class="lang-py prettyprint-override"><code>arr = [False for _ in (range(faces.shape[0]))]
  for i in selected_face_indices:
      arr[i] = True
  boolean_mask_from_selected_face_indices = arr
  </code></pre>
  
  <p>is obviously better, but I would still like to avoid that loop somehow</p>