Skip to content

Commit

Permalink
Call .map() if pandas version is 2.1.0 or greater
Browse files Browse the repository at this point in the history
  • Loading branch information
timmens committed Mar 3, 2024
1 parent d7d53ec commit ef5f01a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
19 changes: 15 additions & 4 deletions src/estimagic/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from pathlib import Path
import pandas as pd
from packaging import version

import plotly.express as px

Expand All @@ -19,9 +21,9 @@
CRITERION_PENALTY_SLOPE = 0.1
CRITERION_PENALTY_CONSTANT = 100

# =====================================================================================
# ======================================================================================
# Check Available Packages
# =====================================================================================
# ======================================================================================

try:
from petsc4py import PETSc # noqa: F401
Expand Down Expand Up @@ -103,9 +105,18 @@
IS_NUMBA_INSTALLED = True


# =================================================================================
# ======================================================================================
# Check if pandas version is newer or equal to version 2.1.0
# ======================================================================================

IS_PANDAS_VERSION_NEWER_OR_EQUAL_TO_2_1_0 = version.parse(
pd.__version__
) >= version.parse("2.1.0")


# ======================================================================================
# Dashboard Defaults
# =================================================================================
# ======================================================================================

Y_RANGE_PADDING = 0.05
Y_RANGE_PADDING_UNITS = "absolute"
Expand Down
4 changes: 2 additions & 2 deletions src/estimagic/optimization/optimize_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
import pandas as pd

from estimagic.utilities import to_pickle
from estimagic.utilities import to_pickle, pandas_df_map


@dataclass
Expand Down Expand Up @@ -128,7 +128,7 @@ def _format_convergence_report(report, algorithm):
report = pd.DataFrame.from_dict(report)
columns = ["one_step", "five_steps"]

table = report[columns].applymap(_format_float).astype(str)
table = pandas_df_map(report[columns], _format_float).astype(str)

for col in "one_step", "five_steps":
table[col] = table[col] + _create_stars(report[col])
Expand Down
26 changes: 26 additions & 0 deletions src/estimagic/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import numpy as np
import pandas as pd
from scipy.linalg import ldl, qr
from estimagic.config import IS_PANDAS_VERSION_NEWER_OR_EQUAL_TO_2_1_0

with warnings.catch_warnings():
warnings.simplefilter("ignore", category=UserWarning)
Expand Down Expand Up @@ -321,3 +322,28 @@ def get_rng(seed):
else:
raise TypeError("seed type must be in {None, int, numpy.random.Generator}.")
return rng


def pandas_df_map(df, func, na_action=None, **kwargs):
"""Apply a function to a Dataframe elementwise.
pandas has depricated the .applymap() function with version 2.1.0. This function
calls either .map() (if pandas version is greater or equal to 2.1.0) or .applymap()
(if pandas version is smaller than 2.1.0).
Args:
df (pd.DataFrame): A pandas DataFrame.
func (callable): Python function, returns a single value from a single value.
na_action (str): If 'ignore', propagate NaN values, without passing them to
func. If None, pass NaN values to func. Default is None.
**kwargs: Additional keyword arguments to pass as keywords arguments to func.
Returns:
pd.DataFrame: Transformed DataFrame.
"""
if IS_PANDAS_VERSION_NEWER_OR_EQUAL_TO_2_1_0:
out = df.map(func, na_action=na_action, **kwargs)
else:
out = df.applymap(func, na_action=na_action, **kwargs)

Check warning on line 348 in src/estimagic/utilities.py

View check run for this annotation

Codecov / codecov/patch

src/estimagic/utilities.py#L348

Added line #L348 was not covered by tests
return out
22 changes: 12 additions & 10 deletions src/estimagic/visualization/estimation_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from functools import partial
from pathlib import Path
from warnings import warn
from estimagic.utilities import pandas_df_map

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -305,7 +306,7 @@ def render_latex(
ci_in_body = False

if ci_in_body:
body.loc[("",)] = body.loc[("",)].applymap("{{{}}}".format).values
body.loc[("",)] = pandas_df_map(body.loc[("",)], "{{{}}}".format).values
if body.columns.nlevels > 1:
column_groups = body.columns.get_level_values(0)
else:
Expand Down Expand Up @@ -1383,22 +1384,23 @@ def _apply_number_format(df_raw, number_format, format_integers):
if isinstance(processed_format, (list, tuple)):
df_formatted = df_raw.copy(deep=True).astype("float")
for formatter in processed_format[:-1]:
df_formatted = df_formatted.applymap(formatter.format).astype("float")
df_formatted = df_formatted.astype("float").applymap(
processed_format[-1].format
df_formatted = pandas_df_map(df_formatted, formatter.format).astype("float")
df_formatted = pandas_df_map(
df_formatted.astype("float"), processed_format[-1].format
)
elif isinstance(processed_format, str):
df_formatted = df_raw.astype("str").applymap(
partial(_format_non_scientific_numbers, format_string=processed_format)
df_formatted = pandas_df_map(
df_raw.astype("str"),
partial(_format_non_scientific_numbers, format_string=processed_format),
)
elif callable(processed_format):
df_formatted = df_raw.applymap(processed_format)
df_formatted = pandas_df_map(df_raw, processed_format)

# Don't format integers: set to original value
if not format_integers:
integer_locs = df_raw.applymap(_is_integer)
df_formatted[integer_locs] = (
df_raw[integer_locs].astype(float).applymap("{:.0f}".format)
integer_locs = pandas_df_map(df_raw, _is_integer)
df_formatted[integer_locs] = pandas_df_map(
df_raw[integer_locs].astype(float), "{:.0f}".format
)
return df_formatted

Expand Down

0 comments on commit ef5f01a

Please sign in to comment.