Skip to content

QST: Is it intended that empty dictionary aggregation raises exception since 1.2.0? #39609

Open
@dchigarev

Description

@dchigarev
  • I have searched the [pandas] tag on StackOverflow for similar questions.

  • I have asked my usage related question on StackOverflow.


Question about pandas

import pandas

df = pandas.DataFrame({"a": [1, 2], "b": [3, 4]})
print(df.agg({})) # ValueError: No objects to concatenate
Traceback
Traceback (most recent call last):
  File "../exp.py", line 4, in <module>
    print(df.agg({}))
  File "/localdisk/dchigare/repos/pandas/pandas/core/frame.py", line 7689, in aggregate
    result, how = self._aggregate(func, axis, *args, **kwargs)
  File "/localdisk/dchigare/repos/pandas/pandas/core/frame.py", line 7723, in _aggregate
    result, how = op.agg()
  File "/localdisk/dchigare/repos/pandas/pandas/core/apply.py", line 177, in agg
    return self.agg_dict_like(_axis), True
  File "/localdisk/dchigare/repos/pandas/pandas/core/apply.py", line 374, in agg_dict_like
    result = concat({k: results[k] for k in keys_to_use}, axis=axis)
  File "/localdisk/dchigare/repos/pandas/pandas/core/reshape/concat.py", line 288, in concat
    op = _Concatenator(
  File "/localdisk/dchigare/repos/pandas/pandas/core/reshape/concat.py", line 345, in __init__
    raise ValueError("No objects to concatenate")
ValueError: No objects to concatenate

Since #37227, aggregation with empty dictionary started to raise ValueError (previously it return an empty frame) which comes from .concat when trying to concat results:

result = concat({k: results[k] for k in keys_to_use}, axis=axis)

Since results are empty, it's logical that it raise exception. But the logic that was touched by #37277 doesn't touch that .concat part, so the behavior should stay the same - return an empty frame.

Previously it goes to the concat branch if any(cond1(x) for x in agg_dict) and now it's all(cond2(x) for x in agg_dict). cond1 and cond2 was written in that way so the condition with any and all are technically the same. But the difference between any and all is that they give the different results on an empty sequences:

>>> all(x for x in [])
True
>>> any(x for x in [])
False

So after any was changed to all it gets to the concat branch even if results are empty and gets an error on .concat.

So the question is, is it desired behavior that now aggregation raises exception on empty dict? And if it is, should it catch these cases in agg_dict_line and give a nicer error?

Metadata

Metadata

Assignees

No one assigned

    Labels

    ApplyApply, Aggregate, Transform, MapBugNeeds DiscussionRequires discussion from core team before further action

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions