Ответ 1
Хорошо, что здесь происходит, это то, что set
не обрабатывается, поскольку он не is_list_like
в _aggregate
:
elif is_list_like(arg) and arg not in compat.string_types:
см. источник
это не is_list_like
поэтому он возвращает None
в цепочку звонков, чтобы закончить в этой строке:
results.append(colg.aggregate(a))
см. источник
это вызывает TypeError
как TypeError: 'type' object is not iterable
который затем поднимает:
if not len(results):
raise ValueError("no results")
см. источник
поэтому, поскольку у нас нет результатов, мы вызываем _aggregate_generic
:
см. источник
это затем вызывает:
result[name] = self._try_cast(func(data, *args, **kwargs)
см. источник
Затем это заканчивается так:
(Pdb) n
> c:\programdata\anaconda3\lib\site-packages\pandas\core\groupby.py(3779)_aggregate_generic()
-> return self._wrap_generic_output(result, obj)
(Pdb) result
{1: {'user_id', 'instructor', 'class_type'}, 2: {'user_id', 'instructor', 'class_type'}, 3: {'user_id', 'instructor', 'class_type'}, 4: {'user_id', 'instructor', 'class_type'}}
Я запускаю немного другую версию панд, но эквивалентная строка источника - https://github.com/pandas-dev/pandas/blob/v0.22.0/pandas/core/groupby.py#L3779
По сути, потому что set
не считается функцией или итерируемым, он просто сворачивается к вызову ctor в последовательной последовательности, которая в этом случае является столбцами, здесь вы можете увидеть тот же эффект:
In [8]:
df.groupby('user_id').agg(lambda x: print(set(x.columns)))
{'class_type', 'instructor', 'user_id'}
{'class_type', 'instructor', 'user_id'}
{'class_type', 'instructor', 'user_id'}
{'class_type', 'instructor', 'user_id'}
Out[8]:
class_type instructor
user_id
1 None None
2 None None
3 None None
4 None None
но когда вы используете lambda
которая является анонимной функцией, это работает так, как ожидалось.