Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: DataFrame.apply with empty dataframe applies the function #49200

Closed
3 tasks done
JoakimZachrisson opened this issue Oct 20, 2022 · 7 comments
Closed
3 tasks done
Labels
Apply Apply, Aggregate, Transform, Map Bug Needs Discussion Requires discussion from core team before further action Regression Functionality that used to work in a prior pandas version

Comments

@JoakimZachrisson
Copy link

JoakimZachrisson commented Oct 20, 2022

Pandas version checks

  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of pandas.

  • I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

import pandas as pd

values = []


def my_fun(x):
    values.append(x["a"])


empty_df = pd.DataFrame(columns=["a"])
empty_df.apply(my_fun, axis=1)

# >= 1.5.0 values contains [nan]
# < 1.5.0 values contains []
print(f"values contains {values}")

Issue Description

Prior to version 1.5.0, applying a function to an empty frame didn't apply the function. After some experiments with pandas 1.4.4, I discovered that the function is actually applied with an empty series as input, and access of the series values raised an exception that is caught and silenced. From a user perspective, it seemed like the function wasn't applied at all.

In 1.5.0 and 1.5.1, the function applied to an empty dataframe is applied with a series of NaN.

I'm not sure if this is actually a bug, but it's a recent change in behavior. I don't think this new behavior is what any user would expect. To me, the intuitive behavior would be that the function isn't executed at all.

Expected Behavior

import pandas as pd

values = []


def my_fun(x):
    values.append(x["a"])


empty_df = pd.DataFrame(columns=["a"])
empty_df.apply(my_fun, axis=1)
assert not values

Installed Versions

INSTALLED VERSIONS

commit : 91111fd
python : 3.10.4.final.0
python-bits : 64
OS : Linux
OS-release : 4.15.0-194-generic
Version : #205-Ubuntu SMP Fri Sep 16 19:49:27 UTC 2022
machine : x86_64
processor : x86_64
byteorder : little
LC_ALL : None
LANG : en_US.UTF-8
LOCALE : en_US.UTF-8

pandas : 1.5.1
numpy : 1.22.1
pytz : 2022.4
dateutil : 2.8.2
setuptools : 64.0.3
pip : 22.2.2
Cython : None
pytest : 7.1.2
hypothesis : None
sphinx : None
blosc : None
feather : None
xlsxwriter : 3.0.3
lxml.etree : 4.9.1
html5lib : 1.1
pymysql : None
psycopg2 : None
jinja2 : 3.1.2
IPython : 8.5.0
pandas_datareader: None
bs4 : 4.11.1
bottleneck : None
brotli : 1.0.9
fastparquet : None
fsspec : None
gcsfs : None
matplotlib : 3.6.0
numba : None
numexpr : None
odfpy : None
openpyxl : None
pandas_gbq : None
pyarrow : None
pyreadstat : None
pyxlsb : None
s3fs : None
scipy : 1.8.1
snappy : None
sqlalchemy : None
tables : None
tabulate : 0.8.10
xarray : None
xlrd : None
xlwt : 1.3.0
zstandard : None
tzdata : None

@JoakimZachrisson JoakimZachrisson added Bug Needs Triage Issue that has not been reviewed by a pandas team member labels Oct 20, 2022
@phofl
Copy link
Member

phofl commented Oct 20, 2022

commit fa76d819252733065e4311eb03e5beea66d3792c
Author: Khor Chean Wei <[email protected]>
Date:   Wed Jul 6 00:53:33 2022 +0800

    BUG Fix: pd.apply returns a dataframe when empty dataframe instead of a series (#47222)

#47222

@phofl phofl added Regression Functionality that used to work in a prior pandas version Apply Apply, Aggregate, Transform, Map and removed Needs Triage Issue that has not been reviewed by a pandas team member labels Oct 20, 2022
@phofl phofl added this to the 1.5.2 milestone Oct 20, 2022
@datapythonista datapythonista modified the milestones: 1.5.2, 1.5.3 Nov 15, 2022
@RaphSku
Copy link
Contributor

RaphSku commented Nov 19, 2022

take

@RaphSku RaphSku removed their assignment Nov 28, 2022
@datapythonista datapythonista modified the milestones: 1.5.3, 1.5.4 Jan 18, 2023
@datapythonista datapythonista modified the milestones: 1.5.4, 2.0 Feb 27, 2023
@mroeschke mroeschke modified the milestones: 2.0, 2.1 Mar 27, 2023
@msoukharev
Copy link

The way I see it, the current API sets expectations that we can identify reduction implicitly. To do that we need to get the information on the return type of the function. Currently we can only do it at run time, and this implies that the function argument to DataFrame::apply must be executed at least once.

I can see how this can be overcome with some effort, open to discussion

A simple workaround would be to pass return_type='reduction'

@mroeschke
Copy link
Member

I agree that the new behavior is worse, but I am not sure the silent "do nothing" behavior is great either. Technically there is no row to apply func too, so it's like calling func without passing an argument. IMO possibly raising in this case is the most informative behavior

@mroeschke mroeschke removed this from the 2.1 milestone Aug 22, 2023
@mroeschke mroeschke added the Needs Discussion Requires discussion from core team before further action label Aug 22, 2023
@JoakimZachrisson
Copy link
Author

return_type='reduction'

raising seems like a good behavior!

@rhshadrach
Copy link
Member

To tackle something like this, I think we need to come to an agreement how pandas operates on empty objects across all the incarnations of apply (Series, DataFrame[axis=0/1], GroupBy, Resample, Window). Otherwise it feels like we are playing wackamole, with behavior changing on various objects but not working toward a consistent API.

In short - I think this should be closed in favor of #47959 (which needs someone to champion).

@mroeschke
Copy link
Member

Ah didn't know about #47959, yeah agreed closing in favor of that issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Apply Apply, Aggregate, Transform, Map Bug Needs Discussion Requires discussion from core team before further action Regression Functionality that used to work in a prior pandas version
Projects
None yet
Development

No branches or pull requests

7 participants