Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pandas/core/ops/docstrings.py: 95%
57 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2Templating for ops docstrings
3"""
4from __future__ import annotations
7def make_flex_doc(op_name: str, typ: str) -> str:
8 """
9 Make the appropriate substitutions for the given operation and class-typ
10 into either _flex_doc_SERIES or _flex_doc_FRAME to return the docstring
11 to attach to a generated method.
13 Parameters
14 ----------
15 op_name : str {'__add__', '__sub__', ... '__eq__', '__ne__', ...}
16 typ : str {series, 'dataframe']}
18 Returns
19 -------
20 doc : str
21 """
22 op_name = op_name.replace("__", "")
23 op_desc = _op_descriptions[op_name]
25 op_desc_op = op_desc["op"]
26 assert op_desc_op is not None # for mypy
27 if op_name.startswith("r"):
28 equiv = "other " + op_desc_op + " " + typ
29 elif op_name == "divmod":
30 equiv = f"{op_name}({typ}, other)"
31 else:
32 equiv = typ + " " + op_desc_op + " other"
34 if typ == "series":
35 base_doc = _flex_doc_SERIES
36 if op_desc["reverse"]:
37 base_doc += _see_also_reverse_SERIES.format(
38 reverse=op_desc["reverse"], see_also_desc=op_desc["see_also_desc"]
39 )
40 doc_no_examples = base_doc.format(
41 desc=op_desc["desc"],
42 op_name=op_name,
43 equiv=equiv,
44 series_returns=op_desc["series_returns"],
45 )
46 ser_example = op_desc["series_examples"]
47 if ser_example: 47 ↛ 50line 47 didn't jump to line 50, because the condition on line 47 was never false
48 doc = doc_no_examples + ser_example
49 else:
50 doc = doc_no_examples
51 elif typ == "dataframe": 51 ↛ 60line 51 didn't jump to line 60, because the condition on line 51 was never false
52 base_doc = _flex_doc_FRAME
53 doc = base_doc.format(
54 desc=op_desc["desc"],
55 op_name=op_name,
56 equiv=equiv,
57 reverse=op_desc["reverse"],
58 )
59 else:
60 raise AssertionError("Invalid typ argument.")
61 return doc
64_common_examples_algebra_SERIES = """
65Examples
66--------
67>>> a = pd.Series([1, 1, 1, np.nan], index=['a', 'b', 'c', 'd'])
68>>> a
69a 1.0
70b 1.0
71c 1.0
72d NaN
73dtype: float64
74>>> b = pd.Series([1, np.nan, 1, np.nan], index=['a', 'b', 'd', 'e'])
75>>> b
76a 1.0
77b NaN
78d 1.0
79e NaN
80dtype: float64"""
82_common_examples_comparison_SERIES = """
83Examples
84--------
85>>> a = pd.Series([1, 1, 1, np.nan, 1], index=['a', 'b', 'c', 'd', 'e'])
86>>> a
87a 1.0
88b 1.0
89c 1.0
90d NaN
91e 1.0
92dtype: float64
93>>> b = pd.Series([0, 1, 2, np.nan, 1], index=['a', 'b', 'c', 'd', 'f'])
94>>> b
95a 0.0
96b 1.0
97c 2.0
98d NaN
99f 1.0
100dtype: float64"""
102_add_example_SERIES = (
103 _common_examples_algebra_SERIES
104 + """
105>>> a.add(b, fill_value=0)
106a 2.0
107b 1.0
108c 1.0
109d 1.0
110e NaN
111dtype: float64
112"""
113)
115_sub_example_SERIES = (
116 _common_examples_algebra_SERIES
117 + """
118>>> a.subtract(b, fill_value=0)
119a 0.0
120b 1.0
121c 1.0
122d -1.0
123e NaN
124dtype: float64
125"""
126)
128_mul_example_SERIES = (
129 _common_examples_algebra_SERIES
130 + """
131>>> a.multiply(b, fill_value=0)
132a 1.0
133b 0.0
134c 0.0
135d 0.0
136e NaN
137dtype: float64
138"""
139)
141_div_example_SERIES = (
142 _common_examples_algebra_SERIES
143 + """
144>>> a.divide(b, fill_value=0)
145a 1.0
146b inf
147c inf
148d 0.0
149e NaN
150dtype: float64
151"""
152)
154_floordiv_example_SERIES = (
155 _common_examples_algebra_SERIES
156 + """
157>>> a.floordiv(b, fill_value=0)
158a 1.0
159b NaN
160c NaN
161d 0.0
162e NaN
163dtype: float64
164"""
165)
167_divmod_example_SERIES = (
168 _common_examples_algebra_SERIES
169 + """
170>>> a.divmod(b, fill_value=0)
171(a 1.0
172 b NaN
173 c NaN
174 d 0.0
175 e NaN
176 dtype: float64,
177 a 0.0
178 b NaN
179 c NaN
180 d 0.0
181 e NaN
182 dtype: float64)
183"""
184)
186_mod_example_SERIES = (
187 _common_examples_algebra_SERIES
188 + """
189>>> a.mod(b, fill_value=0)
190a 0.0
191b NaN
192c NaN
193d 0.0
194e NaN
195dtype: float64
196"""
197)
198_pow_example_SERIES = (
199 _common_examples_algebra_SERIES
200 + """
201>>> a.pow(b, fill_value=0)
202a 1.0
203b 1.0
204c 1.0
205d 0.0
206e NaN
207dtype: float64
208"""
209)
211_ne_example_SERIES = (
212 _common_examples_algebra_SERIES
213 + """
214>>> a.ne(b, fill_value=0)
215a False
216b True
217c True
218d True
219e True
220dtype: bool
221"""
222)
224_eq_example_SERIES = (
225 _common_examples_algebra_SERIES
226 + """
227>>> a.eq(b, fill_value=0)
228a True
229b False
230c False
231d False
232e False
233dtype: bool
234"""
235)
237_lt_example_SERIES = (
238 _common_examples_comparison_SERIES
239 + """
240>>> a.lt(b, fill_value=0)
241a False
242b False
243c True
244d False
245e False
246f True
247dtype: bool
248"""
249)
251_le_example_SERIES = (
252 _common_examples_comparison_SERIES
253 + """
254>>> a.le(b, fill_value=0)
255a False
256b True
257c True
258d False
259e False
260f True
261dtype: bool
262"""
263)
265_gt_example_SERIES = (
266 _common_examples_comparison_SERIES
267 + """
268>>> a.gt(b, fill_value=0)
269a True
270b False
271c False
272d False
273e True
274f False
275dtype: bool
276"""
277)
279_ge_example_SERIES = (
280 _common_examples_comparison_SERIES
281 + """
282>>> a.ge(b, fill_value=0)
283a True
284b True
285c False
286d False
287e True
288f False
289dtype: bool
290"""
291)
293_returns_series = """Series\n The result of the operation."""
295_returns_tuple = """2-Tuple of Series\n The result of the operation."""
297_op_descriptions: dict[str, dict[str, str | None]] = {
298 # Arithmetic Operators
299 "add": {
300 "op": "+",
301 "desc": "Addition",
302 "reverse": "radd",
303 "series_examples": _add_example_SERIES,
304 "series_returns": _returns_series,
305 },
306 "sub": {
307 "op": "-",
308 "desc": "Subtraction",
309 "reverse": "rsub",
310 "series_examples": _sub_example_SERIES,
311 "series_returns": _returns_series,
312 },
313 "mul": {
314 "op": "*",
315 "desc": "Multiplication",
316 "reverse": "rmul",
317 "series_examples": _mul_example_SERIES,
318 "series_returns": _returns_series,
319 "df_examples": None,
320 },
321 "mod": {
322 "op": "%",
323 "desc": "Modulo",
324 "reverse": "rmod",
325 "series_examples": _mod_example_SERIES,
326 "series_returns": _returns_series,
327 },
328 "pow": {
329 "op": "**",
330 "desc": "Exponential power",
331 "reverse": "rpow",
332 "series_examples": _pow_example_SERIES,
333 "series_returns": _returns_series,
334 "df_examples": None,
335 },
336 "truediv": {
337 "op": "/",
338 "desc": "Floating division",
339 "reverse": "rtruediv",
340 "series_examples": _div_example_SERIES,
341 "series_returns": _returns_series,
342 "df_examples": None,
343 },
344 "floordiv": {
345 "op": "//",
346 "desc": "Integer division",
347 "reverse": "rfloordiv",
348 "series_examples": _floordiv_example_SERIES,
349 "series_returns": _returns_series,
350 "df_examples": None,
351 },
352 "divmod": {
353 "op": "divmod",
354 "desc": "Integer division and modulo",
355 "reverse": "rdivmod",
356 "series_examples": _divmod_example_SERIES,
357 "series_returns": _returns_tuple,
358 "df_examples": None,
359 },
360 # Comparison Operators
361 "eq": {
362 "op": "==",
363 "desc": "Equal to",
364 "reverse": None,
365 "series_examples": _eq_example_SERIES,
366 "series_returns": _returns_series,
367 },
368 "ne": {
369 "op": "!=",
370 "desc": "Not equal to",
371 "reverse": None,
372 "series_examples": _ne_example_SERIES,
373 "series_returns": _returns_series,
374 },
375 "lt": {
376 "op": "<",
377 "desc": "Less than",
378 "reverse": None,
379 "series_examples": _lt_example_SERIES,
380 "series_returns": _returns_series,
381 },
382 "le": {
383 "op": "<=",
384 "desc": "Less than or equal to",
385 "reverse": None,
386 "series_examples": _le_example_SERIES,
387 "series_returns": _returns_series,
388 },
389 "gt": {
390 "op": ">",
391 "desc": "Greater than",
392 "reverse": None,
393 "series_examples": _gt_example_SERIES,
394 "series_returns": _returns_series,
395 },
396 "ge": {
397 "op": ">=",
398 "desc": "Greater than or equal to",
399 "reverse": None,
400 "series_examples": _ge_example_SERIES,
401 "series_returns": _returns_series,
402 },
403}
405_py_num_ref = """see
406 `Python documentation
407 <https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types>`_
408 for more details"""
409_op_names = list(_op_descriptions.keys())
410for key in _op_names:
411 reverse_op = _op_descriptions[key]["reverse"]
412 if reverse_op is not None:
413 _op_descriptions[reverse_op] = _op_descriptions[key].copy()
414 _op_descriptions[reverse_op]["reverse"] = key
415 _op_descriptions[key][
416 "see_also_desc"
417 ] = f"Reverse of the {_op_descriptions[key]['desc']} operator, {_py_num_ref}"
418 _op_descriptions[reverse_op][
419 "see_also_desc"
420 ] = f"Element-wise {_op_descriptions[key]['desc']}, {_py_num_ref}"
422_flex_doc_SERIES = """
423Return {desc} of series and other, element-wise (binary operator `{op_name}`).
425Equivalent to ``{equiv}``, but with support to substitute a fill_value for
426missing data in either one of the inputs.
428Parameters
429----------
430other : Series or scalar value
431level : int or name
432 Broadcast across a level, matching Index values on the
433 passed MultiIndex level.
434fill_value : None or float value, default None (NaN)
435 Fill existing missing (NaN) values, and any new element needed for
436 successful Series alignment, with this value before computation.
437 If data in both corresponding Series locations is missing
438 the result of filling (at that location) will be missing.
439axis : {{0 or 'index'}}
440 Unused. Parameter needed for compatibility with DataFrame.
442Returns
443-------
444{series_returns}
445"""
447_see_also_reverse_SERIES = """
448See Also
449--------
450Series.{reverse} : {see_also_desc}.
451"""
453_flex_doc_FRAME = """
454Get {desc} of dataframe and other, element-wise (binary operator `{op_name}`).
456Equivalent to ``{equiv}``, but with support to substitute a fill_value
457for missing data in one of the inputs. With reverse version, `{reverse}`.
459Among flexible wrappers (`add`, `sub`, `mul`, `div`, `mod`, `pow`) to
460arithmetic operators: `+`, `-`, `*`, `/`, `//`, `%`, `**`.
462Parameters
463----------
464other : scalar, sequence, Series, dict or DataFrame
465 Any single or multiple element data structure, or list-like object.
466axis : {{0 or 'index', 1 or 'columns'}}
467 Whether to compare by the index (0 or 'index') or columns.
468 (1 or 'columns'). For Series input, axis to match Series index on.
469level : int or label
470 Broadcast across a level, matching Index values on the
471 passed MultiIndex level.
472fill_value : float or None, default None
473 Fill existing missing (NaN) values, and any new element needed for
474 successful DataFrame alignment, with this value before computation.
475 If data in both corresponding DataFrame locations is missing
476 the result will be missing.
478Returns
479-------
480DataFrame
481 Result of the arithmetic operation.
483See Also
484--------
485DataFrame.add : Add DataFrames.
486DataFrame.sub : Subtract DataFrames.
487DataFrame.mul : Multiply DataFrames.
488DataFrame.div : Divide DataFrames (float division).
489DataFrame.truediv : Divide DataFrames (float division).
490DataFrame.floordiv : Divide DataFrames (integer division).
491DataFrame.mod : Calculate modulo (remainder after division).
492DataFrame.pow : Calculate exponential power.
494Notes
495-----
496Mismatched indices will be unioned together.
498Examples
499--------
500>>> df = pd.DataFrame({{'angles': [0, 3, 4],
501... 'degrees': [360, 180, 360]}},
502... index=['circle', 'triangle', 'rectangle'])
503>>> df
504 angles degrees
505circle 0 360
506triangle 3 180
507rectangle 4 360
509Add a scalar with operator version which return the same
510results.
512>>> df + 1
513 angles degrees
514circle 1 361
515triangle 4 181
516rectangle 5 361
518>>> df.add(1)
519 angles degrees
520circle 1 361
521triangle 4 181
522rectangle 5 361
524Divide by constant with reverse version.
526>>> df.div(10)
527 angles degrees
528circle 0.0 36.0
529triangle 0.3 18.0
530rectangle 0.4 36.0
532>>> df.rdiv(10)
533 angles degrees
534circle inf 0.027778
535triangle 3.333333 0.055556
536rectangle 2.500000 0.027778
538Subtract a list and Series by axis with operator version.
540>>> df - [1, 2]
541 angles degrees
542circle -1 358
543triangle 2 178
544rectangle 3 358
546>>> df.sub([1, 2], axis='columns')
547 angles degrees
548circle -1 358
549triangle 2 178
550rectangle 3 358
552>>> df.sub(pd.Series([1, 1, 1], index=['circle', 'triangle', 'rectangle']),
553... axis='index')
554 angles degrees
555circle -1 359
556triangle 2 179
557rectangle 3 359
559Multiply a dictionary by axis.
561>>> df.mul({{'angles': 0, 'degrees': 2}})
562 angles degrees
563circle 0 720
564triangle 0 360
565rectangle 0 720
567>>> df.mul({{'circle': 0, 'triangle': 2, 'rectangle': 3}}, axis='index')
568 angles degrees
569circle 0 0
570triangle 6 360
571rectangle 12 1080
573Multiply a DataFrame of different shape with operator version.
575>>> other = pd.DataFrame({{'angles': [0, 3, 4]}},
576... index=['circle', 'triangle', 'rectangle'])
577>>> other
578 angles
579circle 0
580triangle 3
581rectangle 4
583>>> df * other
584 angles degrees
585circle 0 NaN
586triangle 9 NaN
587rectangle 16 NaN
589>>> df.mul(other, fill_value=0)
590 angles degrees
591circle 0 0.0
592triangle 9 0.0
593rectangle 16 0.0
595Divide by a MultiIndex by level.
597>>> df_multindex = pd.DataFrame({{'angles': [0, 3, 4, 4, 5, 6],
598... 'degrees': [360, 180, 360, 360, 540, 720]}},
599... index=[['A', 'A', 'A', 'B', 'B', 'B'],
600... ['circle', 'triangle', 'rectangle',
601... 'square', 'pentagon', 'hexagon']])
602>>> df_multindex
603 angles degrees
604A circle 0 360
605 triangle 3 180
606 rectangle 4 360
607B square 4 360
608 pentagon 5 540
609 hexagon 6 720
611>>> df.div(df_multindex, level=1, fill_value=0)
612 angles degrees
613A circle NaN 1.0
614 triangle 1.0 1.0
615 rectangle 1.0 1.0
616B square 0.0 0.0
617 pentagon 0.0 0.0
618 hexagon 0.0 0.0
619"""
621_flex_comp_doc_FRAME = """
622Get {desc} of dataframe and other, element-wise (binary operator `{op_name}`).
624Among flexible wrappers (`eq`, `ne`, `le`, `lt`, `ge`, `gt`) to comparison
625operators.
627Equivalent to `==`, `!=`, `<=`, `<`, `>=`, `>` with support to choose axis
628(rows or columns) and level for comparison.
630Parameters
631----------
632other : scalar, sequence, Series, or DataFrame
633 Any single or multiple element data structure, or list-like object.
634axis : {{0 or 'index', 1 or 'columns'}}, default 'columns'
635 Whether to compare by the index (0 or 'index') or columns
636 (1 or 'columns').
637level : int or label
638 Broadcast across a level, matching Index values on the passed
639 MultiIndex level.
641Returns
642-------
643DataFrame of bool
644 Result of the comparison.
646See Also
647--------
648DataFrame.eq : Compare DataFrames for equality elementwise.
649DataFrame.ne : Compare DataFrames for inequality elementwise.
650DataFrame.le : Compare DataFrames for less than inequality
651 or equality elementwise.
652DataFrame.lt : Compare DataFrames for strictly less than
653 inequality elementwise.
654DataFrame.ge : Compare DataFrames for greater than inequality
655 or equality elementwise.
656DataFrame.gt : Compare DataFrames for strictly greater than
657 inequality elementwise.
659Notes
660-----
661Mismatched indices will be unioned together.
662`NaN` values are considered different (i.e. `NaN` != `NaN`).
664Examples
665--------
666>>> df = pd.DataFrame({{'cost': [250, 150, 100],
667... 'revenue': [100, 250, 300]}},
668... index=['A', 'B', 'C'])
669>>> df
670 cost revenue
671A 250 100
672B 150 250
673C 100 300
675Comparison with a scalar, using either the operator or method:
677>>> df == 100
678 cost revenue
679A False True
680B False False
681C True False
683>>> df.eq(100)
684 cost revenue
685A False True
686B False False
687C True False
689When `other` is a :class:`Series`, the columns of a DataFrame are aligned
690with the index of `other` and broadcast:
692>>> df != pd.Series([100, 250], index=["cost", "revenue"])
693 cost revenue
694A True True
695B True False
696C False True
698Use the method to control the broadcast axis:
700>>> df.ne(pd.Series([100, 300], index=["A", "D"]), axis='index')
701 cost revenue
702A True False
703B True True
704C True True
705D True True
707When comparing to an arbitrary sequence, the number of columns must
708match the number elements in `other`:
710>>> df == [250, 100]
711 cost revenue
712A True True
713B False False
714C False False
716Use the method to control the axis:
718>>> df.eq([250, 250, 100], axis='index')
719 cost revenue
720A True False
721B False True
722C True False
724Compare to a DataFrame of different shape.
726>>> other = pd.DataFrame({{'revenue': [300, 250, 100, 150]}},
727... index=['A', 'B', 'C', 'D'])
728>>> other
729 revenue
730A 300
731B 250
732C 100
733D 150
735>>> df.gt(other)
736 cost revenue
737A False False
738B False False
739C False True
740D False False
742Compare to a MultiIndex by level.
744>>> df_multindex = pd.DataFrame({{'cost': [250, 150, 100, 150, 300, 220],
745... 'revenue': [100, 250, 300, 200, 175, 225]}},
746... index=[['Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2'],
747... ['A', 'B', 'C', 'A', 'B', 'C']])
748>>> df_multindex
749 cost revenue
750Q1 A 250 100
751 B 150 250
752 C 100 300
753Q2 A 150 200
754 B 300 175
755 C 220 225
757>>> df.le(df_multindex, level=1)
758 cost revenue
759Q1 A True True
760 B True True
761 C True True
762Q2 A False True
763 B True False
764 C True False
765"""