SQL GROUPING SETS in Python using Pandas
About this part:

def grouper(df,grpby=None,aggfunc=None):
    uniqcols = (i for i in grpby if len(df[i].unique()) == 1)
    pwrset = (i for i in powerset(grpby))
    s = set()
    for uniqcol in uniqcols:
        for i in pwrset:
            if uniqcol in i:
                s.add(i) # add a level of aggregation only when non-redundant



The two optional arguments are in fact required by the function.
The convention is that i is a loop variable of type int.
Bug: pwrset is a generator expression. As such it can only be iterated through once, just like the iterator returned from powerset(grpby). Using square brackets [] instead of () would turn it into a list comprehension and fix the bug.
Changing the other generator expression into a list comprehension would allow you to swap the order of the nested for loops. This would be more natural since the nested loop is filtering pwrset, and more efficient because you could break out of the inner loop after first s.add(i). Then s does not even need to be a set (because the rest of the code merely iterates over s). If you make uniqcols a set instead, the inner loop could be avoided altogether.


Revised code:

def grouper(df, grpby, aggfunc):
    uniqcols = set(col for col in grpby if len(df[col].unique()) == 1)
    s = [cols for cols in powerset(grpby) if not uniqcols.isdisjoint(cols)]