title: Numpy group by multiple vectors, get group indices
body: <p>I have several numpy arrays; I want to build a groupby method that would have group ids for these arrays. It will then allow me to index these arrays on the group id to perform operations on the groups.</p>
  
  <p>For an example:</p>
  
  <pre><code>import numpy as np
  import pandas as pd
  a = np.array([1,1,1,2,2,3])
  b = np.array([1,2,2,2,3,3])
  
  def group_np(groupcols):
      groupby = np.array([''.join([str(b) for b in bs]) for bs in zip(*[c for c in groupcols])])
      _, groupby = np.unique(groupby, return_invesrse=True)
     return groupby
  
  def group_pd(groupcols):
      df = pd.DataFrame(groupcols[0])
      for i in range(1, len(groupcols)):
          df[i] = groupcols[i]
      for i in range(len(groupcols)):
          df[i] = df[i].fillna(-1)
      return df.groupby(list(range(len(groupcols)))).grouper.group_info[0]
  </code></pre>
  
  <p>Outputs:</p>
  
  <pre><code>group_np([a,b]) -&gt; [0, 1, 1, 2, 3, 4]
  group_pd([a,b]) -&gt; [0, 1, 1, 2, 3, 4]
  </code></pre>
  
  <p>Is there a more efficient way of implementing it, ideally in pure numpy? The bottleneck currently seems to be building a vector that would have unique values for each group - at the moment I am doing that by concatenating the values for each vector as strings.</p>
  
  <p>I want this to work for any number of input vectors, which can have millions of elements.</p>
  
  <p>Edit: here is another testcase:</p>
  
  <pre><code>a = np.array([1,2,1,1,1,2,3,1])
  b = np.array([1,2,2,2,2,3,3,2])
  </code></pre>
  
  <p>Here, group elements 2,3,4,7 should all be the same.</p>
  
  <p>Edit2: adding some benchmarks.</p>
  
  <pre><code>a = np.random.randint(1, 1000, 30000000)
  b = np.random.randint(1, 1000, 30000000)
  c = np.random.randint(1, 1000, 30000000)
  
  def group_np2(groupcols):
      _, groupby = np.unique(np.stack(groupcols), return_inverse=True, axis=1)
      return groupby
  
  %timeit group_np2([a,b,c])
  # 25.1 s +/- 1.06 s per loop (mean +/- std. dev. of 7 runs, 1 loop each)
  %timeit group_pd([a,b,c])
  # 21.7 s +/- 646 ms per loop (mean +/- std. dev. of 7 runs, 1 loop each)
  </code></pre>