|
74 | 74 | ResType = dict[int, Any]
|
75 | 75 |
|
76 | 76 |
|
| 77 | +class BaseExecutionEngine(abc.ABC): |
| 78 | + """ |
| 79 | + Base class for execution engines for map and apply methods. |
| 80 | +
|
| 81 | + An execution engine receives all the parameters of a call to |
| 82 | + ``apply`` or ``map``, such as the data container, the function, |
| 83 | + etc. and takes care of running the execution. |
| 84 | +
|
| 85 | + Supporting different engines allows functions to be JIT compiled, |
| 86 | + run in parallel, and others. Besides the default executor which |
| 87 | + simply runs the code with the Python interpreter and pandas. |
| 88 | + """ |
| 89 | + |
| 90 | + @staticmethod |
| 91 | + @abc.abstractmethod |
| 92 | + def map( |
| 93 | + data: Series | DataFrame | np.ndarray, |
| 94 | + func: AggFuncType, |
| 95 | + args: tuple, |
| 96 | + kwargs: dict[str, Any], |
| 97 | + decorator: Callable | None, |
| 98 | + skip_na: bool, |
| 99 | + ): |
| 100 | + """ |
| 101 | + Executor method to run functions elementwise. |
| 102 | +
|
| 103 | + In general, pandas uses ``map`` for running functions elementwise, |
| 104 | + but ``Series.apply`` with the default ``by_row='compat'`` will also |
| 105 | + call this executor function. |
| 106 | +
|
| 107 | + Parameters |
| 108 | + ---------- |
| 109 | + data : Series, DataFrame or NumPy ndarray |
| 110 | + The object to use for the data. Some methods implement a ``raw`` |
| 111 | + parameter which will convert the original pandas object to a |
| 112 | + NumPy array, which will then be passed here to the executor. |
| 113 | + func : function or NumPy ufunc |
| 114 | + The function to execute. |
| 115 | + args : tuple |
| 116 | + Positional arguments to be passed to ``func``. |
| 117 | + kwargs : dict |
| 118 | + Keyword arguments to be passed to ``func``. |
| 119 | + decorator : function, optional |
| 120 | + For JIT compilers and other engines that need to decorate the |
| 121 | + function ``func``, this is the decorator to use. While the |
| 122 | + executor may already know which is the decorator to use, this |
| 123 | + is useful as for a single executor the user can specify for |
| 124 | + example ``numba.jit`` or ``numba.njit(nogil=True)``, and this |
| 125 | + decorator parameter will contain the exact decorator from the |
| 126 | + executor the user wants to use. |
| 127 | + skip_na : bool |
| 128 | + Whether the function should be called for missing values or not. |
| 129 | + This is specified by the pandas user as ``map(na_action=None)`` |
| 130 | + or ``map(na_action='ignore')``. |
| 131 | + """ |
| 132 | + |
| 133 | + @staticmethod |
| 134 | + @abc.abstractmethod |
| 135 | + def apply( |
| 136 | + data: Series | DataFrame | np.ndarray, |
| 137 | + func: AggFuncType, |
| 138 | + args: tuple, |
| 139 | + kwargs: dict[str, Any], |
| 140 | + decorator: Callable, |
| 141 | + axis: Axis, |
| 142 | + ): |
| 143 | + """ |
| 144 | + Executor method to run functions by an axis. |
| 145 | +
|
| 146 | + While we can see ``map`` as executing the function for each cell |
| 147 | + in a ``DataFrame`` (or ``Series``), ``apply`` will execute the |
| 148 | + function for each column (or row). |
| 149 | +
|
| 150 | + Parameters |
| 151 | + ---------- |
| 152 | + data : Series, DataFrame or NumPy ndarray |
| 153 | + The object to use for the data. Some methods implement a ``raw`` |
| 154 | + parameter which will convert the original pandas object to a |
| 155 | + NumPy array, which will then be passed here to the executor. |
| 156 | + func : function or NumPy ufunc |
| 157 | + The function to execute. |
| 158 | + args : tuple |
| 159 | + Positional arguments to be passed to ``func``. |
| 160 | + kwargs : dict |
| 161 | + Keyword arguments to be passed to ``func``. |
| 162 | + decorator : function, optional |
| 163 | + For JIT compilers and other engines that need to decorate the |
| 164 | + function ``func``, this is the decorator to use. While the |
| 165 | + executor may already know which is the decorator to use, this |
| 166 | + is useful as for a single executor the user can specify for |
| 167 | + example ``numba.jit`` or ``numba.njit(nogil=True)``, and this |
| 168 | + decorator parameter will contain the exact decorator from the |
| 169 | + executor the user wants to use. |
| 170 | + axis : {0 or 'index', 1 or 'columns'} |
| 171 | + 0 or 'index' should execute the function passing each column as |
| 172 | + parameter. 1 or 'columns' should execute the function passing |
| 173 | + each row as parameter. The default executor engine passes rows |
| 174 | + as pandas ``Series``. Other executor engines should probably |
| 175 | + expect functions to be implemented this way for compatibility. |
| 176 | + But passing rows as other data structures is technically possible |
| 177 | + as far as the function ``func`` is implemented accordingly. |
| 178 | + """ |
| 179 | + |
| 180 | + |
77 | 181 | def frame_apply(
|
78 | 182 | obj: DataFrame,
|
79 | 183 | func: AggFuncType,
|
|
0 commit comments