def get_group_index_sorter(group_index, ngroups):
count = len(group_index)<EOL>alpha = <NUM_LIT:0.0>  <EOL>beta = <NUM_LIT:1.0>  <EOL>do_groupsort = (count > <NUM_LIT:0> and ((alpha + beta * ngroups) <<EOL>(count * np.log(count))))<EOL>if do_groupsort:<EOL><INDENT>sorter, _ = algos.groupsort_indexer(ensure_int64(group_index),<EOL>ngroups)<EOL>return ensure_platform_int(sorter)<EOL><DEDENT>else:<EOL><INDENT>return group_index.argsort(kind='<STR_LIT>')<EOL><DEDENT>
algos.groupsort_indexer implements `counting sort` and it is at least
O(ngroups), where
    ngroups = prod(shape)
    shape = map(len, keys)
that is, linear in the number of combinations (cartesian product) of unique
values of groupby keys. This can be huge when doing multi-key groupby.
np.argsort(kind='mergesort') is O(count x log(count)) where count is the
length of the data-frame;
Both algorithms are `stable` sort and that is necessary for correctness of
groupby operations. e.g. consider:
    df.groupby(key)[col].transform('first')