Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pandas/core/ops/docstrings.py: 97%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

61 statements  

1""" 

2Templating for ops docstrings 

3""" 

4 

5from __future__ import annotations 

6 

7 

8def make_flex_doc(op_name: str, typ: str) -> str: 

9 """ 

10 Make the appropriate substitutions for the given operation and class-typ 

11 into either _flex_doc_SERIES or _flex_doc_FRAME to return the docstring 

12 to attach to a generated method. 

13 

14 Parameters 

15 ---------- 

16 op_name : str {'__add__', '__sub__', ... '__eq__', '__ne__', ...} 

17 typ : str {series, 'dataframe']} 

18 

19 Returns 

20 ------- 

21 doc : str 

22 """ 

23 op_name = op_name.replace("__", "") 

24 op_desc = _op_descriptions[op_name] 

25 

26 op_desc_op = op_desc["op"] 

27 assert op_desc_op is not None # for mypy 

28 if op_name.startswith("r"): 

29 equiv = f"other {op_desc_op} {typ}" 

30 elif op_name == "divmod": 

31 equiv = f"{op_name}({typ}, other)" 

32 else: 

33 equiv = f"{typ} {op_desc_op} other" 

34 

35 if typ == "series": 

36 base_doc = _flex_doc_SERIES 

37 if op_desc["reverse"]: 

38 base_doc += _see_also_reverse_SERIES.format( 

39 reverse=op_desc["reverse"], see_also_desc=op_desc["see_also_desc"] 

40 ) 

41 doc_no_examples = base_doc.format( 

42 desc=op_desc["desc"], 

43 op_name=op_name, 

44 equiv=equiv, 

45 series_returns=op_desc["series_returns"], 

46 ) 

47 ser_example = op_desc["series_examples"] 

48 if ser_example: 

49 doc = doc_no_examples + ser_example 

50 else: 

51 doc = doc_no_examples 

52 elif typ == "dataframe": 

53 if op_name in ["eq", "ne", "le", "lt", "ge", "gt"]: 

54 base_doc = _flex_comp_doc_FRAME 

55 doc = _flex_comp_doc_FRAME.format( 

56 op_name=op_name, 

57 desc=op_desc["desc"], 

58 ) 

59 else: 

60 base_doc = _flex_doc_FRAME 

61 doc = base_doc.format( 

62 desc=op_desc["desc"], 

63 op_name=op_name, 

64 equiv=equiv, 

65 reverse=op_desc["reverse"], 

66 ) 

67 else: 

68 raise AssertionError("Invalid typ argument.") 

69 return doc 

70 

71 

72_common_examples_algebra_SERIES = """ 

73Examples 

74-------- 

75>>> a = pd.Series([1, 1, 1, np.nan], index=['a', 'b', 'c', 'd']) 

76>>> a 

77a 1.0 

78b 1.0 

79c 1.0 

80d NaN 

81dtype: float64 

82>>> b = pd.Series([1, np.nan, 1, np.nan], index=['a', 'b', 'd', 'e']) 

83>>> b 

84a 1.0 

85b NaN 

86d 1.0 

87e NaN 

88dtype: float64""" 

89 

90_common_examples_comparison_SERIES = """ 

91Examples 

92-------- 

93>>> a = pd.Series([1, 1, 1, np.nan, 1], index=['a', 'b', 'c', 'd', 'e']) 

94>>> a 

95a 1.0 

96b 1.0 

97c 1.0 

98d NaN 

99e 1.0 

100dtype: float64 

101>>> b = pd.Series([0, 1, 2, np.nan, 1], index=['a', 'b', 'c', 'd', 'f']) 

102>>> b 

103a 0.0 

104b 1.0 

105c 2.0 

106d NaN 

107f 1.0 

108dtype: float64""" 

109 

110_add_example_SERIES = ( 

111 _common_examples_algebra_SERIES 

112 + """ 

113>>> a.add(b, fill_value=0) 

114a 2.0 

115b 1.0 

116c 1.0 

117d 1.0 

118e NaN 

119dtype: float64 

120""" 

121) 

122 

123_sub_example_SERIES = ( 

124 _common_examples_algebra_SERIES 

125 + """ 

126>>> a.subtract(b, fill_value=0) 

127a 0.0 

128b 1.0 

129c 1.0 

130d -1.0 

131e NaN 

132dtype: float64 

133""" 

134) 

135 

136_mul_example_SERIES = ( 

137 _common_examples_algebra_SERIES 

138 + """ 

139>>> a.multiply(b, fill_value=0) 

140a 1.0 

141b 0.0 

142c 0.0 

143d 0.0 

144e NaN 

145dtype: float64 

146""" 

147) 

148 

149_div_example_SERIES = ( 

150 _common_examples_algebra_SERIES 

151 + """ 

152>>> a.divide(b, fill_value=0) 

153a 1.0 

154b inf 

155c inf 

156d 0.0 

157e NaN 

158dtype: float64 

159""" 

160) 

161 

162_floordiv_example_SERIES = ( 

163 _common_examples_algebra_SERIES 

164 + """ 

165>>> a.floordiv(b, fill_value=0) 

166a 1.0 

167b inf 

168c inf 

169d 0.0 

170e NaN 

171dtype: float64 

172""" 

173) 

174 

175_divmod_example_SERIES = ( 

176 _common_examples_algebra_SERIES 

177 + """ 

178>>> a.divmod(b, fill_value=0) 

179(a 1.0 

180 b inf 

181 c inf 

182 d 0.0 

183 e NaN 

184 dtype: float64, 

185 a 0.0 

186 b NaN 

187 c NaN 

188 d 0.0 

189 e NaN 

190 dtype: float64) 

191""" 

192) 

193 

194_mod_example_SERIES = ( 

195 _common_examples_algebra_SERIES 

196 + """ 

197>>> a.mod(b, fill_value=0) 

198a 0.0 

199b NaN 

200c NaN 

201d 0.0 

202e NaN 

203dtype: float64 

204""" 

205) 

206_pow_example_SERIES = ( 

207 _common_examples_algebra_SERIES 

208 + """ 

209>>> a.pow(b, fill_value=0) 

210a 1.0 

211b 1.0 

212c 1.0 

213d 0.0 

214e NaN 

215dtype: float64 

216""" 

217) 

218 

219_ne_example_SERIES = ( 

220 _common_examples_algebra_SERIES 

221 + """ 

222>>> a.ne(b, fill_value=0) 

223a False 

224b True 

225c True 

226d True 

227e True 

228dtype: bool 

229""" 

230) 

231 

232_eq_example_SERIES = ( 

233 _common_examples_algebra_SERIES 

234 + """ 

235>>> a.eq(b, fill_value=0) 

236a True 

237b False 

238c False 

239d False 

240e False 

241dtype: bool 

242""" 

243) 

244 

245_lt_example_SERIES = ( 

246 _common_examples_comparison_SERIES 

247 + """ 

248>>> a.lt(b, fill_value=0) 

249a False 

250b False 

251c True 

252d False 

253e False 

254f True 

255dtype: bool 

256""" 

257) 

258 

259_le_example_SERIES = ( 

260 _common_examples_comparison_SERIES 

261 + """ 

262>>> a.le(b, fill_value=0) 

263a False 

264b True 

265c True 

266d False 

267e False 

268f True 

269dtype: bool 

270""" 

271) 

272 

273_gt_example_SERIES = ( 

274 _common_examples_comparison_SERIES 

275 + """ 

276>>> a.gt(b, fill_value=0) 

277a True 

278b False 

279c False 

280d False 

281e True 

282f False 

283dtype: bool 

284""" 

285) 

286 

287_ge_example_SERIES = ( 

288 _common_examples_comparison_SERIES 

289 + """ 

290>>> a.ge(b, fill_value=0) 

291a True 

292b True 

293c False 

294d False 

295e True 

296f False 

297dtype: bool 

298""" 

299) 

300 

301_returns_series = """Series\n The result of the operation.""" 

302 

303_returns_tuple = """2-Tuple of Series\n The result of the operation.""" 

304 

305_op_descriptions: dict[str, dict[str, str | None]] = { 

306 # Arithmetic Operators 

307 "add": { 

308 "op": "+", 

309 "desc": "Addition", 

310 "reverse": "radd", 

311 "series_examples": _add_example_SERIES, 

312 "series_returns": _returns_series, 

313 }, 

314 "sub": { 

315 "op": "-", 

316 "desc": "Subtraction", 

317 "reverse": "rsub", 

318 "series_examples": _sub_example_SERIES, 

319 "series_returns": _returns_series, 

320 }, 

321 "mul": { 

322 "op": "*", 

323 "desc": "Multiplication", 

324 "reverse": "rmul", 

325 "series_examples": _mul_example_SERIES, 

326 "series_returns": _returns_series, 

327 "df_examples": None, 

328 }, 

329 "mod": { 

330 "op": "%", 

331 "desc": "Modulo", 

332 "reverse": "rmod", 

333 "series_examples": _mod_example_SERIES, 

334 "series_returns": _returns_series, 

335 }, 

336 "pow": { 

337 "op": "**", 

338 "desc": "Exponential power", 

339 "reverse": "rpow", 

340 "series_examples": _pow_example_SERIES, 

341 "series_returns": _returns_series, 

342 "df_examples": None, 

343 }, 

344 "truediv": { 

345 "op": "/", 

346 "desc": "Floating division", 

347 "reverse": "rtruediv", 

348 "series_examples": _div_example_SERIES, 

349 "series_returns": _returns_series, 

350 "df_examples": None, 

351 }, 

352 "floordiv": { 

353 "op": "//", 

354 "desc": "Integer division", 

355 "reverse": "rfloordiv", 

356 "series_examples": _floordiv_example_SERIES, 

357 "series_returns": _returns_series, 

358 "df_examples": None, 

359 }, 

360 "divmod": { 

361 "op": "divmod", 

362 "desc": "Integer division and modulo", 

363 "reverse": "rdivmod", 

364 "series_examples": _divmod_example_SERIES, 

365 "series_returns": _returns_tuple, 

366 "df_examples": None, 

367 }, 

368 # Comparison Operators 

369 "eq": { 

370 "op": "==", 

371 "desc": "Equal to", 

372 "reverse": None, 

373 "series_examples": _eq_example_SERIES, 

374 "series_returns": _returns_series, 

375 }, 

376 "ne": { 

377 "op": "!=", 

378 "desc": "Not equal to", 

379 "reverse": "eq", 

380 "series_examples": _ne_example_SERIES, 

381 "series_returns": _returns_series, 

382 }, 

383 "lt": { 

384 "op": "<", 

385 "desc": "Less than", 

386 "reverse": None, 

387 "series_examples": _lt_example_SERIES, 

388 "series_returns": _returns_series, 

389 }, 

390 "le": { 

391 "op": "<=", 

392 "desc": "Less than or equal to", 

393 "reverse": None, 

394 "series_examples": _le_example_SERIES, 

395 "series_returns": _returns_series, 

396 }, 

397 "gt": { 

398 "op": ">", 

399 "desc": "Greater than", 

400 "reverse": "lt", 

401 "series_examples": _gt_example_SERIES, 

402 "series_returns": _returns_series, 

403 }, 

404 "ge": { 

405 "op": ">=", 

406 "desc": "Greater than or equal to", 

407 "reverse": "le", 

408 "series_examples": _ge_example_SERIES, 

409 "series_returns": _returns_series, 

410 }, 

411} 

412 

413_py_num_ref = """see 

414 `Python documentation 

415 <https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types>`_ 

416 for more details""" 

417_op_names = list(_op_descriptions.keys()) 

418for key in _op_names: 

419 reverse_op = _op_descriptions[key]["reverse"] 

420 if reverse_op is not None: 

421 _op_descriptions[reverse_op] = _op_descriptions[key].copy() 

422 _op_descriptions[reverse_op]["reverse"] = key 

423 _op_descriptions[key]["see_also_desc"] = ( 

424 f"Reverse of the {_op_descriptions[key]['desc']} operator, {_py_num_ref}" 

425 ) 

426 _op_descriptions[reverse_op]["see_also_desc"] = ( 

427 f"Element-wise {_op_descriptions[key]['desc']}, {_py_num_ref}" 

428 ) 

429 

430_flex_doc_SERIES = """ 

431Return {desc} of series and other, element-wise (binary operator `{op_name}`). 

432 

433Equivalent to ``{equiv}``, but with support to substitute a fill_value for 

434missing data in either one of the inputs. 

435 

436Parameters 

437---------- 

438other : object 

439 When a Series is provided, will align on indexes. For all other types, 

440 will behave the same as ``==`` but with possibly different results due 

441 to the other arguments. 

442level : int or name 

443 Broadcast across a level, matching Index values on the 

444 passed MultiIndex level. 

445fill_value : None or float value, default None (NaN) 

446 Fill existing missing (NaN) values, and any new element needed for 

447 successful Series alignment, with this value before computation. 

448 If data in both corresponding Series locations is missing 

449 the result of filling (at that location) will be missing. 

450axis : {{0 or 'index'}} 

451 Unused. Parameter needed for compatibility with DataFrame. 

452 

453Returns 

454------- 

455{series_returns} 

456""" 

457 

458_see_also_reverse_SERIES = """ 

459See Also 

460-------- 

461Series.{reverse} : {see_also_desc}. 

462""" 

463 

464_flex_doc_FRAME = """ 

465Get {desc} of dataframe and other, element-wise (binary operator `{op_name}`). 

466 

467Equivalent to ``{equiv}``, but with support to substitute a fill_value 

468for missing data in one of the inputs. With reverse version, `{reverse}`. 

469 

470Among flexible wrappers (`add`, `sub`, `mul`, `div`, `floordiv`, `mod`, `pow`) to 

471arithmetic operators: `+`, `-`, `*`, `/`, `//`, `%`, `**`. 

472 

473Parameters 

474---------- 

475other : scalar, sequence, Series, dict or DataFrame 

476 Any single or multiple element data structure, or list-like object. 

477axis : {{0 or 'index', 1 or 'columns'}} 

478 Whether to compare by the index (0 or 'index') or columns. 

479 (1 or 'columns'). For Series input, axis to match Series index on. 

480level : int or label 

481 Broadcast across a level, matching Index values on the 

482 passed MultiIndex level. 

483fill_value : float or None, default None 

484 Fill existing missing (NaN) values, and any new element needed for 

485 successful DataFrame alignment, with this value before computation. 

486 If data in both corresponding DataFrame locations is missing 

487 the result will be missing. 

488 

489Returns 

490------- 

491DataFrame 

492 Result of the arithmetic operation. 

493 

494See Also 

495-------- 

496DataFrame.add : Add DataFrames. 

497DataFrame.sub : Subtract DataFrames. 

498DataFrame.mul : Multiply DataFrames. 

499DataFrame.div : Divide DataFrames (float division). 

500DataFrame.truediv : Divide DataFrames (float division). 

501DataFrame.floordiv : Divide DataFrames (integer division). 

502DataFrame.mod : Calculate modulo (remainder after division). 

503DataFrame.pow : Calculate exponential power. 

504 

505Notes 

506----- 

507Mismatched indices will be unioned together. 

508 

509Examples 

510-------- 

511>>> df = pd.DataFrame({{'angles': [0, 3, 4], 

512... 'degrees': [360, 180, 360]}}, 

513... index=['circle', 'triangle', 'rectangle']) 

514>>> df 

515 angles degrees 

516circle 0 360 

517triangle 3 180 

518rectangle 4 360 

519 

520Add a scalar with operator version which return the same 

521results. 

522 

523>>> df + 1 

524 angles degrees 

525circle 1 361 

526triangle 4 181 

527rectangle 5 361 

528 

529>>> df.add(1) 

530 angles degrees 

531circle 1 361 

532triangle 4 181 

533rectangle 5 361 

534 

535Divide by constant with reverse version. 

536 

537>>> df.div(10) 

538 angles degrees 

539circle 0.0 36.0 

540triangle 0.3 18.0 

541rectangle 0.4 36.0 

542 

543>>> df.rdiv(10) 

544 angles degrees 

545circle inf 0.027778 

546triangle 3.333333 0.055556 

547rectangle 2.500000 0.027778 

548 

549Subtract a list and Series by axis with operator version. 

550 

551>>> df - [1, 2] 

552 angles degrees 

553circle -1 358 

554triangle 2 178 

555rectangle 3 358 

556 

557>>> df.sub([1, 2], axis='columns') 

558 angles degrees 

559circle -1 358 

560triangle 2 178 

561rectangle 3 358 

562 

563>>> df.sub(pd.Series([1, 1, 1], index=['circle', 'triangle', 'rectangle']), 

564... axis='index') 

565 angles degrees 

566circle -1 359 

567triangle 2 179 

568rectangle 3 359 

569 

570Multiply a dictionary by axis. 

571 

572>>> df.mul({{'angles': 0, 'degrees': 2}}) 

573 angles degrees 

574circle 0 720 

575triangle 0 360 

576rectangle 0 720 

577 

578>>> df.mul({{'circle': 0, 'triangle': 2, 'rectangle': 3}}, axis='index') 

579 angles degrees 

580circle 0 0 

581triangle 6 360 

582rectangle 12 1080 

583 

584Multiply a DataFrame of different shape with operator version. 

585 

586>>> other = pd.DataFrame({{'angles': [0, 3, 4]}}, 

587... index=['circle', 'triangle', 'rectangle']) 

588>>> other 

589 angles 

590circle 0 

591triangle 3 

592rectangle 4 

593 

594>>> df * other 

595 angles degrees 

596circle 0 NaN 

597triangle 9 NaN 

598rectangle 16 NaN 

599 

600>>> df.mul(other, fill_value=0) 

601 angles degrees 

602circle 0 0.0 

603triangle 9 0.0 

604rectangle 16 0.0 

605 

606Divide by a MultiIndex by level. 

607 

608>>> df_multindex = pd.DataFrame({{'angles': [0, 3, 4, 4, 5, 6], 

609... 'degrees': [360, 180, 360, 360, 540, 720]}}, 

610... index=[['A', 'A', 'A', 'B', 'B', 'B'], 

611... ['circle', 'triangle', 'rectangle', 

612... 'square', 'pentagon', 'hexagon']]) 

613>>> df_multindex 

614 angles degrees 

615A circle 0 360 

616 triangle 3 180 

617 rectangle 4 360 

618B square 4 360 

619 pentagon 5 540 

620 hexagon 6 720 

621 

622>>> df.div(df_multindex, level=1, fill_value=0) 

623 angles degrees 

624A circle NaN 1.0 

625 triangle 1.0 1.0 

626 rectangle 1.0 1.0 

627B square 0.0 0.0 

628 pentagon 0.0 0.0 

629 hexagon 0.0 0.0 

630 

631>>> df_pow = pd.DataFrame({{'A': [2, 3, 4, 5], 

632... 'B': [6, 7, 8, 9]}}) 

633>>> df_pow.pow(2) 

634 A B 

6350 4 36 

6361 9 49 

6372 16 64 

6383 25 81 

639""" 

640 

641_flex_comp_doc_FRAME = """ 

642Get {desc} of dataframe and other, element-wise (binary operator `{op_name}`). 

643 

644Among flexible wrappers (`eq`, `ne`, `le`, `lt`, `ge`, `gt`) to comparison 

645operators. 

646 

647Equivalent to `==`, `!=`, `<=`, `<`, `>=`, `>` with support to choose axis 

648(rows or columns) and level for comparison. 

649 

650Parameters 

651---------- 

652other : scalar, sequence, Series, or DataFrame 

653 Any single or multiple element data structure, or list-like object. 

654axis : {{0 or 'index', 1 or 'columns'}}, default 'columns' 

655 Whether to compare by the index (0 or 'index') or columns 

656 (1 or 'columns'). 

657level : int or label 

658 Broadcast across a level, matching Index values on the passed 

659 MultiIndex level. 

660 

661Returns 

662------- 

663DataFrame of bool 

664 Result of the comparison. 

665 

666See Also 

667-------- 

668DataFrame.eq : Compare DataFrames for equality elementwise. 

669DataFrame.ne : Compare DataFrames for inequality elementwise. 

670DataFrame.le : Compare DataFrames for less than inequality 

671 or equality elementwise. 

672DataFrame.lt : Compare DataFrames for strictly less than 

673 inequality elementwise. 

674DataFrame.ge : Compare DataFrames for greater than inequality 

675 or equality elementwise. 

676DataFrame.gt : Compare DataFrames for strictly greater than 

677 inequality elementwise. 

678 

679Notes 

680----- 

681Mismatched indices will be unioned together. 

682`NaN` values are considered different (i.e. `NaN` != `NaN`). 

683 

684Examples 

685-------- 

686>>> df = pd.DataFrame({{'cost': [250, 150, 100], 

687... 'revenue': [100, 250, 300]}}, 

688... index=['A', 'B', 'C']) 

689>>> df 

690 cost revenue 

691A 250 100 

692B 150 250 

693C 100 300 

694 

695Comparison with a scalar, using either the operator or method: 

696 

697>>> df == 100 

698 cost revenue 

699A False True 

700B False False 

701C True False 

702 

703>>> df.eq(100) 

704 cost revenue 

705A False True 

706B False False 

707C True False 

708 

709When `other` is a :class:`Series`, the columns of a DataFrame are aligned 

710with the index of `other` and broadcast: 

711 

712>>> df != pd.Series([100, 250], index=["cost", "revenue"]) 

713 cost revenue 

714A True True 

715B True False 

716C False True 

717 

718Use the method to control the broadcast axis: 

719 

720>>> df.ne(pd.Series([100, 300], index=["A", "D"]), axis='index') 

721 cost revenue 

722A True False 

723B True True 

724C True True 

725D True True 

726 

727When comparing to an arbitrary sequence, the number of columns must 

728match the number elements in `other`: 

729 

730>>> df == [250, 100] 

731 cost revenue 

732A True True 

733B False False 

734C False False 

735 

736Use the method to control the axis: 

737 

738>>> df.eq([250, 250, 100], axis='index') 

739 cost revenue 

740A True False 

741B False True 

742C True False 

743 

744Compare to a DataFrame of different shape. 

745 

746>>> other = pd.DataFrame({{'revenue': [300, 250, 100, 150]}}, 

747... index=['A', 'B', 'C', 'D']) 

748>>> other 

749 revenue 

750A 300 

751B 250 

752C 100 

753D 150 

754 

755>>> df.gt(other) 

756 cost revenue 

757A False False 

758B False False 

759C False True 

760D False False 

761 

762Compare to a MultiIndex by level. 

763 

764>>> df_multindex = pd.DataFrame({{'cost': [250, 150, 100, 150, 300, 220], 

765... 'revenue': [100, 250, 300, 200, 175, 225]}}, 

766... index=[['Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2'], 

767... ['A', 'B', 'C', 'A', 'B', 'C']]) 

768>>> df_multindex 

769 cost revenue 

770Q1 A 250 100 

771 B 150 250 

772 C 100 300 

773Q2 A 150 200 

774 B 300 175 

775 C 220 225 

776 

777>>> df.le(df_multindex, level=1) 

778 cost revenue 

779Q1 A True True 

780 B True True 

781 C True True 

782Q2 A False True 

783 B True False 

784 C True False 

785"""