title: How to do alpha compositing with a list of RGBA data in numpy arrays?
body: <p>Following <a href="https://www.wikiwand.com/en/Alpha_compositing#/Alpha_blending" rel="nofollow noreferrer">this</a> formula for alpha blending two color values, I wish to apply this to <em>n</em> numpy arrays of rgba image data (though the expected use-case will, in practice, have a very low upper bound of arrays, probably > 5). In context, this process will be constrained to arrays of identical shape.</p>
  
  <p>I could in theory achieve this through iteration, but expect that this would be computationally intensive and terribly inefficient. </p>
  
  <p>What is the most efficient way to apply a function between two elements in the same position between two arrays <em>across the entire array</em>?</p>
  
  <p>A loose example:</p>
  
  <pre><code># in context, the numpy arrays come from here, as either numpy data in the 
  # first place or a path
  def import_data(source):
      # first test for an extant numpy array
      try:
          assert(type(source) is np.ndarray)
          data = source
      except AssertionError:
          try:
              exists(source)
              data = add_alpha_channel(np.array(Image.open(source)))
          except IOError:
              raise IOError("Cannot identify image data in file '{0}'".format(source))
          except TypeError:
                  raise TypeError("Cannot identify image data from source.")
  
      return data
  
  # and here is the in-progress method that will, in theory composite the stack of 
  # arrays; it context this is a bit more elaborate; self.width &amp; height are just what  
  # they appear to be—-the final size of the composited output of all layers
  
  def render(self):
          render_surface = np.zeros((self.height, self.width, 4))
          for l in self.__layers:  
              foreground = l.render() # basically this just returns an np array
              # the next four lines just find the regions between two layers to 
              # be composited
              l_x1, l_y1 = l.origin
              l_x2 = l_x1 + foreground.shape[1]
              l_y2 = l_y1 + foreground.shape[0]
              background = render_surface[l_y1: l_y2, l_x1: l_x2]
  
              # at this point, foreground &amp; background contain two identically shaped 
              # arrays to be composited; next line is where the function i'm seeking 
              # ought to go
              render_surface[l_y1: l_y2, l_x1: l_x2] = ?
  </code></pre>