Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pandas/core/strings/accessor.py: 24%

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

632 statements  

1from __future__ import annotations 

2 

3import codecs 

4from functools import wraps 

5import re 

6from typing import ( 

7 TYPE_CHECKING, 

8 Literal, 

9 cast, 

10) 

11import warnings 

12 

13import numpy as np 

14 

15from pandas._config import using_string_dtype 

16 

17from pandas._libs import lib 

18from pandas.util._exceptions import find_stack_level 

19 

20from pandas.core.dtypes.common import ( 

21 ensure_object, 

22 is_bool_dtype, 

23 is_extension_array_dtype, 

24 is_integer, 

25 is_list_like, 

26 is_numeric_dtype, 

27 is_object_dtype, 

28 is_re, 

29 is_string_dtype, 

30) 

31from pandas.core.dtypes.dtypes import ( 

32 ArrowDtype, 

33 CategoricalDtype, 

34) 

35from pandas.core.dtypes.generic import ( 

36 ABCDataFrame, 

37 ABCIndex, 

38 ABCMultiIndex, 

39 ABCSeries, 

40) 

41from pandas.core.dtypes.missing import isna 

42 

43from pandas.core.arrays import ExtensionArray 

44from pandas.core.base import NoNewAttributesMixin 

45from pandas.core.construction import extract_array 

46 

47if TYPE_CHECKING: 

48 from collections.abc import ( 

49 Callable, 

50 Hashable, 

51 Iterator, 

52 ) 

53 

54 from pandas._typing import ( 

55 AlignJoin, 

56 DtypeObj, 

57 F, 

58 NpDtype, 

59 Scalar, 

60 npt, 

61 ) 

62 

63 from pandas import ( 

64 DataFrame, 

65 Index, 

66 Series, 

67 ) 

68 

69_cpython_optimized_encoders = ( 

70 "utf-8", 

71 "utf8", 

72 "latin-1", 

73 "latin1", 

74 "iso-8859-1", 

75 "mbcs", 

76 "ascii", 

77) 

78_cpython_optimized_decoders = (*_cpython_optimized_encoders, "utf-16", "utf-32") 

79 

80 

81def forbid_nonstring_types( 

82 forbidden: list[str] | None, name: str | None = None 

83) -> Callable[[F], F]: 

84 """ 

85 Decorator to forbid specific types for a method of StringMethods. 

86 

87 For calling `.str.{method}` on a Series or Index, it is necessary to first 

88 initialize the :class:`StringMethods` object, and then call the method. 

89 However, different methods allow different input types, and so this can not 

90 be checked during :meth:`StringMethods.__init__`, but must be done on a 

91 per-method basis. This decorator exists to facilitate this process, and 

92 make it explicit which (inferred) types are disallowed by the method. 

93 

94 :meth:`StringMethods.__init__` allows the *union* of types its different 

95 methods allow (after skipping NaNs; see :meth:`StringMethods._validate`), 

96 namely: ['string', 'empty', 'bytes', 'mixed', 'mixed-integer']. 

97 

98 The default string types ['string', 'empty'] are allowed for all methods. 

99 For the additional types ['bytes', 'mixed', 'mixed-integer'], each method 

100 then needs to forbid the types it is not intended for. 

101 

102 Parameters 

103 ---------- 

104 forbidden : list-of-str or None 

105 List of forbidden non-string types, may be one or more of 

106 `['bytes', 'mixed', 'mixed-integer']`. 

107 name : str, default None 

108 Name of the method to use in the error message. By default, this is 

109 None, in which case the name from the method being wrapped will be 

110 copied. However, for working with further wrappers (like _pat_wrapper 

111 and _noarg_wrapper), it is necessary to specify the name. 

112 

113 Returns 

114 ------- 

115 func : wrapper 

116 The method to which the decorator is applied, with an added check that 

117 enforces the inferred type to not be in the list of forbidden types. 

118 

119 Raises 

120 ------ 

121 TypeError 

122 If the inferred type of the underlying data is in `forbidden`. 

123 """ 

124 # deal with None 

125 forbidden = [] if forbidden is None else forbidden 

126 

127 allowed_types = {"string", "empty", "bytes", "mixed", "mixed-integer"} - set( 

128 forbidden 

129 ) 

130 

131 def _forbid_nonstring_types(func: F) -> F: 

132 func_name = func.__name__ if name is None else name 

133 

134 @wraps(func) 

135 def wrapper(self, *args, **kwargs): 

136 if self._inferred_dtype not in allowed_types: 

137 msg = ( 

138 f"Cannot use .str.{func_name} with values of " 

139 f"inferred dtype '{self._inferred_dtype}'." 

140 ) 

141 raise TypeError(msg) 

142 return func(self, *args, **kwargs) 

143 

144 wrapper.__name__ = func_name 

145 return cast("F", wrapper) 

146 

147 return _forbid_nonstring_types 

148 

149 

150class StringMethods(NoNewAttributesMixin): 

151 """ 

152 Vectorized string functions for Series and Index. 

153 

154 NAs stay NA unless handled otherwise by a particular method. 

155 Patterned after Python's string methods, with some inspiration from 

156 R's stringr package. 

157 

158 Parameters 

159 ---------- 

160 data : Series or Index 

161 The content of the Series or Index. 

162 

163 See Also 

164 -------- 

165 Series.str : Vectorized string functions for Series. 

166 Index.str : Vectorized string functions for Index. 

167 

168 Examples 

169 -------- 

170 >>> s = pd.Series(["A_Str_Series"]) 

171 >>> s 

172 0 A_Str_Series 

173 dtype: str 

174 

175 >>> s.str.split("_") 

176 0 [A, Str, Series] 

177 dtype: object 

178 

179 >>> s.str.replace("_", "") 

180 0 AStrSeries 

181 dtype: str 

182 """ 

183 

184 # Note: see the docstring in pandas.core.strings.__init__ 

185 # for an explanation of the implementation. 

186 # TODO: Dispatch all the methods 

187 # Currently the following are not dispatched to the array 

188 # * cat 

189 # * extractall 

190 

191 def __init__(self, data) -> None: 

192 from pandas.core.arrays.string_ import StringDtype 

193 

194 self._inferred_dtype = self._validate(data) 

195 self._is_categorical = isinstance(data.dtype, CategoricalDtype) 

196 self._is_string = isinstance(data.dtype, StringDtype) 

197 self._data = data 

198 

199 self._index = self._name = None 

200 if isinstance(data, ABCSeries): 

201 self._index = data.index 

202 self._name = data.name 

203 

204 # ._values.categories works for both Series/Index 

205 self._parent = data._values.categories if self._is_categorical else data 

206 # save orig to blow up categoricals to the right type 

207 self._orig = data 

208 self._freeze() 

209 

210 @staticmethod 

211 def _validate(data): 

212 """ 

213 Auxiliary function for StringMethods, infers and checks dtype of data. 

214 

215 This is a "first line of defence" at the creation of the StringMethods- 

216 object, and just checks that the dtype is in the 

217 *union* of the allowed types over all string methods below; this 

218 restriction is then refined on a per-method basis using the decorator 

219 @forbid_nonstring_types (more info in the corresponding docstring). 

220 

221 This really should exclude all series/index with any non-string values, 

222 but that isn't practical for performance reasons until we have a str 

223 dtype (GH 9343 / 13877) 

224 

225 Parameters 

226 ---------- 

227 data : The content of the Series 

228 

229 Returns 

230 ------- 

231 dtype : inferred dtype of data 

232 """ 

233 if isinstance(data, ABCMultiIndex): 

234 raise AttributeError( 

235 "Can only use .str accessor with Index, not MultiIndex" 

236 ) 

237 

238 # see _libs/lib.pyx for list of inferred types 

239 allowed_types = ["string", "empty", "bytes", "mixed", "mixed-integer"] 

240 

241 data = extract_array(data) 

242 

243 values = getattr(data, "categories", data) # categorical / normal 

244 

245 inferred_dtype = lib.infer_dtype(values, skipna=True) 

246 

247 if inferred_dtype not in allowed_types: 

248 raise AttributeError( 

249 f"Can only use .str accessor with string values, not {inferred_dtype}" 

250 ) 

251 return inferred_dtype 

252 

253 def __getitem__(self, key): 

254 result = self._data.array._str_getitem(key) 

255 return self._wrap_result(result) 

256 

257 def __iter__(self) -> Iterator: 

258 raise TypeError(f"'{type(self).__name__}' object is not iterable") 

259 

260 def _wrap_result( 

261 self, 

262 result, 

263 name=None, 

264 expand: bool | None = None, 

265 fill_value=np.nan, 

266 returns_string: bool = True, 

267 dtype=None, 

268 ): 

269 from pandas import ( 

270 Index, 

271 MultiIndex, 

272 ) 

273 

274 if not hasattr(result, "ndim") or not hasattr(result, "dtype"): 

275 if isinstance(result, ABCDataFrame): 

276 result = result.__finalize__(self._orig, name="str") 

277 return result 

278 assert result.ndim < 3 

279 

280 # We can be wrapping a string / object / categorical result, in which 

281 # case we'll want to return the same dtype as the input. 

282 # Or we can be wrapping a numeric output, in which case we don't want 

283 # to return a StringArray. 

284 # Ideally the array method returns the right array type. 

285 if expand is None: 

286 # infer from ndim if expand is not specified 

287 expand = result.ndim != 1 

288 elif expand is True and not isinstance(self._orig, ABCIndex): 

289 # required when expand=True is explicitly specified 

290 # not needed when inferred 

291 if isinstance(result.dtype, ArrowDtype): 

292 import pyarrow as pa 

293 

294 from pandas.core.arrays.arrow.array import ArrowExtensionArray 

295 

296 value_lengths = pa.compute.list_value_length(result._pa_array) 

297 max_len = pa.compute.max(value_lengths).as_py() 

298 min_len = pa.compute.min(value_lengths).as_py() 

299 if max_len is None: 

300 # No non-null rows to take a width from. Match the 

301 # object-dtype path below, which expands an all-NA result 

302 # into a single all-NA column and an empty one into no 

303 # columns at all. 

304 max_len = min_len = 1 if len(result) else 0 

305 value_type = result._pa_array.type.value_type 

306 if result._hasna: 

307 # ArrowExtensionArray.fillna doesn't work for list scalars 

308 result = ArrowExtensionArray( 

309 result._pa_array.fill_null([None] * max_len) 

310 ) 

311 if min_len < max_len: 

312 # append nulls to each scalar list element up to max_len 

313 result = ArrowExtensionArray( 

314 pa.compute.list_slice( 

315 result._pa_array, 

316 start=0, 

317 stop=max_len, 

318 return_fixed_size_list=True, 

319 ) 

320 ) 

321 if name is None: 

322 name = range(max_len) 

323 result = ( 

324 pa.compute.list_flatten(result._pa_array) 

325 .to_numpy() 

326 .reshape(len(result), max_len) 

327 ) 

328 columns = {} 

329 for label, res in zip(name, result.T, strict=True): 

330 col = pa.array(res) 

331 if pa.types.is_null(col.type) and not pa.types.is_null(value_type): 

332 # an all-NA column would otherwise land on the null 

333 # type, which no longer supports .str 

334 col = col.cast(value_type) 

335 columns[label] = ArrowExtensionArray(col) 

336 result = columns 

337 elif is_object_dtype(result): 

338 

339 def cons_row(x): 

340 if is_list_like(x): 

341 return x 

342 else: 

343 return [x] 

344 

345 result = [cons_row(x) for x in result] 

346 if result: 

347 if not self._is_string: 

348 # propagate nan values to match longest sequence 

349 # (GH 18450) 

350 max_len = max(len(x) for x in result) 

351 result = [ 

352 x * max_len if len(x) == 0 or x[0] is np.nan else x 

353 for x in result 

354 ] 

355 

356 # GH#65751 right-pad ragged rows to a common length so the 

357 # DataFrame constructor below isn't relied on to NaN-pad 

358 # mismatched-length sequences (now deprecated). Filling 

359 # with None matches the constructor's previous behavior. 

360 max_len = max(len(x) for x in result) 

361 result = [ 

362 list(x) + [None] * (max_len - len(x)) if len(x) < max_len else x 

363 for x in result 

364 ] 

365 

366 if not isinstance(expand, bool): 

367 raise ValueError("expand must be True or False") 

368 

369 if expand is False: 

370 # if expand is False, result should have the same name 

371 # as the original otherwise specified 

372 if name is None: 

373 name = getattr(result, "name", None) 

374 if name is None: 

375 # do not use logical or, _orig may be a DataFrame 

376 # which has "name" column 

377 name = self._orig.name 

378 

379 # Wait until we are sure result is a Series or Index before 

380 # checking attributes (GH 12180) 

381 if isinstance(self._orig, ABCIndex): 

382 # if result is a boolean np.array, return the np.array 

383 # instead of wrapping it into a boolean Index (GH 8875) 

384 if is_bool_dtype(result): 

385 return result 

386 

387 if expand: 

388 result = list(result) 

389 out: Index = MultiIndex.from_tuples(result, names=name) 

390 if out.nlevels == 1: 

391 # We had all tuples of length-one, which are 

392 # better represented as a regular Index. 

393 out = out.get_level_values(0) 

394 return out 

395 else: 

396 return Index(result, name=name, dtype=dtype, copy=False) 

397 else: 

398 index = self._orig.index 

399 # This is a mess. 

400 _dtype: DtypeObj | str | None = dtype 

401 vdtype = getattr(result, "dtype", None) 

402 if _dtype is not None: 

403 pass 

404 elif self._is_string: 

405 if is_bool_dtype(vdtype): 

406 _dtype = result.dtype 

407 elif returns_string: 

408 _dtype = self._orig.dtype 

409 else: 

410 _dtype = vdtype 

411 elif vdtype is not None: 

412 _dtype = vdtype 

413 

414 if expand: 

415 cons = self._orig._constructor_expanddim 

416 result = cons(result, columns=name, index=index, dtype=_dtype) 

417 else: 

418 # Must be a Series 

419 cons = self._orig._constructor 

420 result = cons(result, name=name, index=index, dtype=_dtype) 

421 result = result.__finalize__(self._orig, method="str") 

422 if name is not None and result.ndim == 1: 

423 # __finalize__ might copy over the original name, but we may 

424 # want the new name (e.g. str.extract). 

425 result.name = name 

426 return result 

427 

428 def _get_series_list(self, others): 

429 """ 

430 Auxiliary function for :meth:`str.cat`. Turn potentially mixed input 

431 into a list of Series (elements without an index must match the length 

432 of the calling Series/Index). 

433 

434 Parameters 

435 ---------- 

436 others : Series, DataFrame, np.ndarray, list-like or list-like of 

437 Objects that are either Series, Index or np.ndarray (1-dim). 

438 

439 Returns 

440 ------- 

441 list of Series 

442 Others transformed into list of Series. 

443 """ 

444 from pandas import ( 

445 DataFrame, 

446 Series, 

447 ) 

448 

449 # self._orig is either Series or Index 

450 idx = self._orig if isinstance(self._orig, ABCIndex) else self._orig.index 

451 

452 # Generally speaking, all objects without an index inherit the index 

453 # `idx` of the calling Series/Index - i.e. must have matching length. 

454 # Objects with an index (i.e. Series/Index/DataFrame) keep their own. 

455 if isinstance(others, ABCSeries): 

456 return [others] 

457 elif isinstance(others, ABCIndex): 

458 return [Series(others, index=idx, dtype=others.dtype)] 

459 elif isinstance(others, ABCDataFrame): 

460 return [others[x] for x in others] 

461 elif isinstance(others, np.ndarray) and others.ndim == 2: 

462 others = DataFrame(others, index=idx) 

463 return [others[x] for x in others] 

464 elif is_list_like(others, allow_sets=False): 

465 try: 

466 others = list(others) # ensure iterators do not get read twice etc 

467 except TypeError: 

468 # e.g. ser.str, raise below 

469 pass 

470 else: 

471 # in case of list-like `others`, all elements must be 

472 # either Series/Index/np.ndarray (1-dim)... 

473 if all( 

474 isinstance(x, (ABCSeries, ABCIndex, ExtensionArray)) 

475 or (isinstance(x, np.ndarray) and x.ndim == 1) 

476 for x in others 

477 ): 

478 los: list[Series] = [] 

479 while others: # iterate through list and append each element 

480 los = los + self._get_series_list(others.pop(0)) 

481 return los 

482 # ... or just strings 

483 elif all(not is_list_like(x) for x in others): 

484 return [Series(others, index=idx)] 

485 raise TypeError( 

486 "others must be Series, Index, DataFrame, np.ndarray " 

487 "or list-like (either containing only strings or " 

488 "containing only objects of type Series/Index/" 

489 "np.ndarray[1-dim])" 

490 ) 

491 

492 @forbid_nonstring_types(["bytes", "mixed", "mixed-integer"]) 

493 def cat( 

494 self, 

495 others=None, 

496 sep: str | None = None, 

497 na_rep=None, 

498 join: AlignJoin = "left", 

499 ) -> str | Series | Index: 

500 """ 

501 Concatenate strings in the Series/Index with given separator. 

502 

503 If `others` is specified, this function concatenates the Series/Index 

504 and elements of `others` element-wise. 

505 If `others` is not passed, then all values in the Series/Index are 

506 concatenated into a single string with a given `sep`. 

507 

508 Parameters 

509 ---------- 

510 others : Series, Index, DataFrame, np.ndarray or list-like 

511 Series, Index, DataFrame, np.ndarray (one- or two-dimensional) and 

512 other list-likes of strings must have the same length as the 

513 calling Series/Index, with the exception of indexed objects (i.e. 

514 Series/Index/DataFrame) if `join` is not None. 

515 

516 If others is a list-like that contains a combination of Series, 

517 Index or np.ndarray (1-dim), then all elements will be unpacked and 

518 must satisfy the above criteria individually. 

519 

520 If others is None, the method returns the concatenation of all 

521 strings in the calling Series/Index. 

522 sep : str, default '' 

523 The separator between the different elements/columns. By default 

524 the empty string `''` is used. 

525 na_rep : str or None, default None 

526 Representation that is inserted for all missing values: 

527 

528 - If `na_rep` is None, and `others` is None, missing values in the 

529 Series/Index are omitted from the result. 

530 - If `na_rep` is None, and `others` is not None, a row containing a 

531 missing value in any of the columns (before concatenation) will 

532 have a missing value in the result. 

533 join : {'left', 'right', 'outer', 'inner'}, default 'left' 

534 Determines the join-style between the calling Series/Index and any 

535 Series/Index/DataFrame in `others` (objects without an index need 

536 to match the length of the calling Series/Index). To disable 

537 alignment, use `.values` on any Series/Index/DataFrame in `others`. 

538 Note: when the caller is an :class:`Index`, its *values* are used 

539 as the index for alignment, so a ``Series`` or ``DataFrame`` in 

540 `others` is aligned against those values rather than positionally. 

541 An ``Index`` or ``np.ndarray`` in `others` has no index of its own 

542 and is always used positionally. 

543 

544 Returns 

545 ------- 

546 str, Series or Index 

547 If `others` is None, `str` is returned, otherwise a `Series/Index` 

548 (same type as caller) of objects is returned. 

549 

550 See Also 

551 -------- 

552 split : Split each string in the Series/Index. 

553 join : Join lists contained as elements in the Series/Index. 

554 

555 Examples 

556 -------- 

557 When not passing `others`, all values are concatenated into a single 

558 string: 

559 

560 >>> s = pd.Series(["a", "b", np.nan, "d"]) 

561 >>> s.str.cat(sep=" ") 

562 'a b d' 

563 

564 By default, NA values in the Series are ignored. Using `na_rep`, they 

565 can be given a representation: 

566 

567 >>> s.str.cat(sep=" ", na_rep="?") 

568 'a b ? d' 

569 

570 If `others` is specified, corresponding values are concatenated with 

571 the separator. Result will be a Series of strings. 

572 

573 >>> s.str.cat(["A", "B", "C", "D"], sep=",") 

574 0 a,A 

575 1 b,B 

576 2 NaN 

577 3 d,D 

578 dtype: str 

579 

580 Missing values will remain missing in the result, but can again be 

581 represented using `na_rep` 

582 

583 >>> s.str.cat(["A", "B", "C", "D"], sep=",", na_rep="-") 

584 0 a,A 

585 1 b,B 

586 2 -,C 

587 3 d,D 

588 dtype: str 

589 

590 If `sep` is not specified, the values are concatenated without 

591 separation. 

592 

593 >>> s.str.cat(["A", "B", "C", "D"], na_rep="-") 

594 0 aA 

595 1 bB 

596 2 -C 

597 3 dD 

598 dtype: str 

599 

600 Series with different indexes can be aligned before concatenation. The 

601 `join`-keyword works as in other methods. 

602 

603 >>> t = pd.Series(["d", "a", "e", "c"], index=[3, 0, 4, 2]) 

604 >>> s.str.cat(t, join="left", na_rep="-") 

605 0 aa 

606 1 b- 

607 2 -c 

608 3 dd 

609 dtype: str 

610 >>> 

611 >>> s.str.cat(t, join="outer", na_rep="-") 

612 0 aa 

613 1 b- 

614 2 -c 

615 3 dd 

616 4 -e 

617 dtype: str 

618 >>> 

619 >>> s.str.cat(t, join="inner", na_rep="-") 

620 0 aa 

621 2 -c 

622 3 dd 

623 dtype: str 

624 >>> 

625 >>> s.str.cat(t, join="right", na_rep="-") 

626 3 dd 

627 0 aa 

628 4 -e 

629 2 -c 

630 dtype: str 

631 

632 When the caller is an :class:`Index`, alignment uses the values of that 

633 ``Index``, so concatenating with a ``Series`` whose index is unrelated 

634 gives missing values: 

635 

636 >>> idx = pd.Index(["a", "b", "c"]) 

637 >>> idx.str.cat(pd.Series(["x", "y", "z"])) 

638 Index([nan, nan, nan], dtype='object') 

639 

640 Use ``.to_numpy()`` (or ``.values``) to concatenate positionally: 

641 

642 >>> idx.str.cat(pd.Series(["x", "y", "z"]).to_numpy()) 

643 Index(['ax', 'by', 'cz'], dtype='str') 

644 

645 For more examples, see :ref:`here <text.concatenate>`. 

646 """ 

647 # TODO: dispatch 

648 from pandas import ( 

649 Index, 

650 Series, 

651 concat, 

652 ) 

653 

654 if isinstance(others, str): 

655 raise ValueError("Did you mean to supply a `sep` keyword?") 

656 if sep is None: 

657 sep = "" 

658 

659 if isinstance(self._orig, ABCIndex): 

660 data = Series(self._orig, index=self._orig, dtype=self._orig.dtype) 

661 else: # Series 

662 data = self._orig 

663 

664 # concatenate Series/Index with itself if no "others" 

665 if others is None: 

666 # error: Incompatible types in assignment (expression has type 

667 # "ndarray", variable has type "Series") 

668 data = ensure_object(data) # type: ignore[assignment] 

669 na_mask = isna(data) 

670 if na_rep is None and na_mask.any(): 

671 return sep.join(data[~na_mask]) 

672 elif na_rep is not None and na_mask.any(): 

673 return sep.join(np.where(na_mask, na_rep, data)) 

674 else: 

675 return sep.join(data) 

676 

677 try: 

678 # turn anything in "others" into lists of Series 

679 others = self._get_series_list(others) 

680 except ValueError as err: # do not catch TypeError raised by _get_series_list 

681 raise ValueError( 

682 "If `others` contains arrays or lists (or other " 

683 "list-likes without an index), these must all be " 

684 "of the same length as the calling Series/Index." 

685 ) from err 

686 

687 # align if required 

688 if any(not data.index.equals(x.index) for x in others): 

689 # Need to add keys for uniqueness in case of duplicate columns 

690 others = concat( 

691 others, 

692 axis=1, 

693 join=(join if join == "inner" else "outer"), 

694 keys=range(len(others)), 

695 sort=False, 

696 ) 

697 data, others = data.align(others, join=join) 

698 others = [others[x] for x in others] # again list of Series 

699 

700 all_cols = [ensure_object(x) for x in [data, *others]] 

701 na_masks = np.array([isna(x) for x in all_cols]) 

702 union_mask = np.logical_or.reduce(na_masks, axis=0) 

703 

704 if na_rep is None and union_mask.any(): 

705 # no na_rep means NaNs for all rows where any column has a NaN 

706 # only necessary if there are actually any NaNs 

707 result = np.empty(len(data), dtype=object) 

708 np.putmask(result, union_mask, np.nan) 

709 

710 not_masked = ~union_mask 

711 result[not_masked] = cat_safe([x[not_masked] for x in all_cols], sep) 

712 elif na_rep is not None and union_mask.any(): 

713 # fill NaNs with na_rep in case there are actually any NaNs 

714 all_cols = [ 

715 np.where(nm, na_rep, col) 

716 for nm, col in zip(na_masks, all_cols, strict=True) 

717 ] 

718 result = cat_safe(all_cols, sep) 

719 else: 

720 # no NaNs - can just concatenate 

721 result = cat_safe(all_cols, sep) 

722 

723 out: Index | Series 

724 if isinstance(self._orig.dtype, CategoricalDtype): 

725 # We need to infer the new categories. 

726 dtype = self._orig.dtype.categories.dtype 

727 else: 

728 dtype = self._orig.dtype 

729 if isinstance(self._orig, ABCIndex): 

730 # add dtype for case that result is all-NA 

731 if isna(result).all(): 

732 dtype = object # type: ignore[assignment] 

733 

734 out = Index(result, dtype=dtype, name=self._orig.name, copy=False) 

735 else: # Series 

736 res_ser = Series( 

737 result, dtype=dtype, index=data.index, name=self._orig.name, copy=False 

738 ) 

739 out = res_ser.__finalize__(self._orig, method="str_cat") 

740 return out 

741 

742 @forbid_nonstring_types(["bytes"]) 

743 def split( 

744 self, 

745 pat: str | re.Pattern | None = None, 

746 *, 

747 n=-1, 

748 expand: bool = False, 

749 regex: bool | None = None, 

750 ): 

751 r""" 

752 Split strings around given separator/delimiter. 

753 

754 Splits the string in the Series/Index from the beginning, 

755 at the specified delimiter string. 

756 

757 Parameters 

758 ---------- 

759 pat : str or compiled regex, optional 

760 String or regular expression to split on. 

761 If not specified, split on whitespace. 

762 n : int, default -1 (all) 

763 Limit number of splits in output. 

764 ``None``, 0 and -1 will be interpreted as return all splits. 

765 expand : bool, default False 

766 Expand the split strings into separate columns. 

767 

768 - If ``True``, return DataFrame/MultiIndex expanding dimensionality. 

769 - If ``False``, return Series/Index, containing lists of strings. 

770 

771 regex : bool, default None 

772 Determines if the passed-in pattern is a regular expression: 

773 

774 - If ``True``, assumes the passed-in pattern is a regular expression 

775 - If ``False``, treats the pattern as a literal string. 

776 - If ``None`` and `pat` length is 1, treats `pat` as a literal string. 

777 - If ``None`` and `pat` length is not 1, treats `pat` as a regular 

778 expression. 

779 - Cannot be set to False if `pat` is a compiled regex 

780 

781 Returns 

782 ------- 

783 Series, Index, DataFrame or MultiIndex 

784 Type matches caller unless ``expand=True`` (see Notes). 

785 

786 Raises 

787 ------ 

788 ValueError 

789 * if `regex` is False and `pat` is a compiled regex 

790 

791 See Also 

792 -------- 

793 Series.str.rsplit : Splits string around given separator/delimiter, 

794 starting from the right. 

795 Series.str.join : Join lists contained as elements in the Series/Index 

796 with passed delimiter. 

797 re.split : Standard library version for split with ``regex=True``. 

798 str.split : Standard library version for split with ``regex=False``. 

799 str.rsplit : Standard library version for rsplit. 

800 

801 Notes 

802 ----- 

803 The handling of the `n` keyword depends on the number of found splits: 

804 

805 - If found splits > `n`, make first `n` splits only 

806 - If found splits <= `n`, make all splits 

807 - If for a certain row the number of found splits is less than the 

808 maximum number of splits found across all rows, append `None` for 

809 padding if ``expand=True`` 

810 

811 If using ``expand=True``, Series and Index callers return DataFrame and 

812 MultiIndex objects, respectively. The number of columns equals the 

813 maximum number of splits found in the data plus one and can be less 

814 than ``n + 1``; `n` is an upper bound on the number of splits, not a 

815 guaranteed output width. To get a fixed number of columns, reindex 

816 the result, e.g. ``.reindex(range(n + 1), axis=1)``. 

817 

818 Use of `regex =False` with a `pat` as a compiled regex will raise an error. 

819 

820 Examples 

821 -------- 

822 >>> s = pd.Series( 

823 ... [ 

824 ... "this is a regular sentence", 

825 ... "https://docs.python.org/3/tutorial/index.html", 

826 ... np.nan, 

827 ... ] 

828 ... ) 

829 >>> s 

830 0 this is a regular sentence 

831 1 https://docs.python.org/3/tutorial/index.html 

832 2 NaN 

833 dtype: str 

834 

835 In the default setting, the string is split by whitespace. 

836 

837 >>> s.str.split() 

838 0 [this, is, a, regular, sentence] 

839 1 [https://docs.python.org/3/tutorial/index.html] 

840 2 NaN 

841 dtype: object 

842 

843 Without the `n` parameter, the outputs of `rsplit` and `split` 

844 are identical. 

845 

846 >>> s.str.rsplit() 

847 0 [this, is, a, regular, sentence] 

848 1 [https://docs.python.org/3/tutorial/index.html] 

849 2 NaN 

850 dtype: object 

851 

852 The `n` parameter can be used to limit the number of splits on the 

853 delimiter. The outputs of `split` and `rsplit` are different. 

854 

855 >>> s.str.split(n=2) 

856 0 [this, is, a regular sentence] 

857 1 [https://docs.python.org/3/tutorial/index.html] 

858 2 NaN 

859 dtype: object 

860 

861 >>> s.str.rsplit(n=2) 

862 0 [this is a, regular, sentence] 

863 1 [https://docs.python.org/3/tutorial/index.html] 

864 2 NaN 

865 dtype: object 

866 

867 The `pat` parameter can be used to split by other characters. 

868 

869 >>> s.str.split(pat="/") 

870 0 [this is a regular sentence] 

871 1 [https:, , docs.python.org, 3, tutorial, index... 

872 2 NaN 

873 dtype: object 

874 

875 When using ``expand=True``, the split elements will expand out into 

876 separate columns. If NaN is present, it is propagated throughout 

877 the columns during the split. 

878 

879 >>> s.str.split(expand=True) 

880 0 1 2 3 4 

881 0 this is a regular sentence 

882 1 https://docs.python.org/3/tutorial/index.html NaN NaN NaN NaN 

883 2 NaN NaN NaN NaN NaN 

884 

885 For slightly more complex use cases like splitting the html document name 

886 from a url, a combination of parameter settings can be used. 

887 

888 >>> s.str.rsplit("/", n=1, expand=True) 

889 0 1 

890 0 this is a regular sentence NaN 

891 1 https://docs.python.org/3/tutorial index.html 

892 2 NaN NaN 

893 

894 Remember to escape special characters when explicitly using regular expressions. 

895 

896 >>> s = pd.Series(["foo and bar plus baz"]) 

897 >>> s.str.split(r"and|plus", expand=True) 

898 0 1 2 

899 0 foo bar baz 

900 

901 Regular expressions can be used to handle urls or file names. 

902 When `pat` is a string and ``regex=None`` (the default), the given `pat` is 

903 compiled as a regex only if ``len(pat) != 1``. 

904 

905 >>> s = pd.Series(["foojpgbar.jpg"]) 

906 >>> s.str.split(r".", expand=True) 

907 0 1 

908 0 foojpgbar jpg 

909 

910 >>> s.str.split(r"\.jpg", expand=True) 

911 0 1 

912 0 foojpgbar 

913 

914 When ``regex=True``, `pat` is interpreted as a regex 

915 

916 >>> s.str.split(r"\.jpg", regex=True, expand=True) 

917 0 1 

918 0 foojpgbar 

919 

920 A compiled regex can be passed as `pat` 

921 

922 >>> import re 

923 >>> s.str.split(re.compile(r"\.jpg"), expand=True) 

924 0 1 

925 0 foojpgbar 

926 

927 When ``regex=False``, `pat` is interpreted as the string itself 

928 

929 >>> s.str.split(r"\.jpg", regex=False, expand=True) 

930 0 

931 0 foojpgbar.jpg 

932 """ 

933 if regex is False and is_re(pat): 

934 raise ValueError( 

935 "Cannot use a compiled regex as replacement pattern with regex=False" 

936 ) 

937 if is_re(pat): 

938 regex = True 

939 result = self._data.array._str_split(pat, n, expand, regex) 

940 if self._data.dtype == "category": 

941 dtype = self._data.dtype.categories.dtype if expand else object 

942 else: 

943 dtype = object if self._data.dtype == object else None 

944 return self._wrap_result( 

945 result, expand=expand, returns_string=expand, dtype=dtype 

946 ) 

947 

948 @forbid_nonstring_types(["bytes"]) 

949 def rsplit(self, pat=None, *, n=-1, expand: bool = False): 

950 """ 

951 Split strings around given separator/delimiter. 

952 

953 Splits the string in the Series/Index from the end, 

954 at the specified delimiter string. 

955 

956 Parameters 

957 ---------- 

958 pat : str, optional 

959 String to split on. Does not support regex. 

960 If not specified, split on whitespace. 

961 n : int, default -1 (all) 

962 Limit number of splits in output. 

963 ``None``, 0 and -1 will be interpreted as return all splits. 

964 expand : bool, default False 

965 Expand the split strings into separate columns. 

966 

967 - If ``True``, return DataFrame/MultiIndex expanding dimensionality. 

968 - If ``False``, return Series/Index, containing lists of strings. 

969 

970 Returns 

971 ------- 

972 Series, Index, DataFrame or MultiIndex 

973 Type matches caller unless ``expand=True`` (see Notes). 

974 

975 See Also 

976 -------- 

977 Series.str.split : Split strings around given separator/delimiter or 

978 regular expression. 

979 Series.str.join : Join lists contained as elements in the Series/Index 

980 with passed delimiter. 

981 re.split : Standard library version for split with ``regex=True``. 

982 str.split : Standard library version for split with ``regex=False``. 

983 str.rsplit : Standard library version for rsplit. 

984 

985 Notes 

986 ----- 

987 The handling of the `n` keyword depends on the number of found splits: 

988 

989 - If found splits > `n`, make first `n` splits only 

990 - If found splits <= `n`, make all splits 

991 - If for a certain row the number of found splits is less than the 

992 maximum number of splits found across all rows, append `None` for 

993 padding if ``expand=True`` 

994 

995 If using ``expand=True``, Series and Index callers return DataFrame and 

996 MultiIndex objects, respectively. The number of columns equals the 

997 maximum number of splits found in the data plus one and can be less 

998 than ``n + 1``; `n` is an upper bound on the number of splits, not a 

999 guaranteed output width. To get a fixed number of columns, reindex 

1000 the result, e.g. ``.reindex(range(n + 1), axis=1)``. 

1001 

1002 Examples 

1003 -------- 

1004 >>> s = pd.Series( 

1005 ... [ 

1006 ... "this is a regular sentence", 

1007 ... "https://docs.python.org/3/tutorial/index.html", 

1008 ... np.nan, 

1009 ... ] 

1010 ... ) 

1011 >>> s 

1012 0 this is a regular sentence 

1013 1 https://docs.python.org/3/tutorial/index.html 

1014 2 NaN 

1015 dtype: str 

1016 

1017 In the default setting, the string is split by whitespace. 

1018 

1019 >>> s.str.split() 

1020 0 [this, is, a, regular, sentence] 

1021 1 [https://docs.python.org/3/tutorial/index.html] 

1022 2 NaN 

1023 dtype: object 

1024 

1025 Without the `n` parameter, the outputs of `rsplit` and `split` 

1026 are identical. 

1027 

1028 >>> s.str.rsplit() 

1029 0 [this, is, a, regular, sentence] 

1030 1 [https://docs.python.org/3/tutorial/index.html] 

1031 2 NaN 

1032 dtype: object 

1033 

1034 The `n` parameter can be used to limit the number of splits on the 

1035 delimiter. The outputs of `split` and `rsplit` are different. 

1036 

1037 >>> s.str.split(n=2) 

1038 0 [this, is, a regular sentence] 

1039 1 [https://docs.python.org/3/tutorial/index.html] 

1040 2 NaN 

1041 dtype: object 

1042 

1043 >>> s.str.rsplit(n=2) 

1044 0 [this is a, regular, sentence] 

1045 1 [https://docs.python.org/3/tutorial/index.html] 

1046 2 NaN 

1047 dtype: object 

1048 

1049 The `pat` parameter can be used to split by other characters. 

1050 

1051 >>> s.str.split(pat="/") 

1052 0 [this is a regular sentence] 

1053 1 [https:, , docs.python.org, 3, tutorial, index... 

1054 2 NaN 

1055 dtype: object 

1056 

1057 When using ``expand=True``, the split elements will expand out into 

1058 separate columns. If NaN is present, it is propagated throughout 

1059 the columns during the split. 

1060 

1061 >>> s.str.split(expand=True) 

1062 0 1 2 3 4 

1063 0 this is a regular sentence 

1064 1 https://docs.python.org/3/tutorial/index.html NaN NaN NaN NaN 

1065 2 NaN NaN NaN NaN NaN 

1066 

1067 For slightly more complex use cases like splitting the html document name 

1068 from a url, a combination of parameter settings can be used. 

1069 

1070 >>> s.str.rsplit("/", n=1, expand=True) 

1071 0 1 

1072 0 this is a regular sentence NaN 

1073 1 https://docs.python.org/3/tutorial index.html 

1074 2 NaN NaN 

1075 """ 

1076 result = self._data.array._str_rsplit(pat, n=n) 

1077 if self._data.dtype == "category": 

1078 dtype = self._data.dtype.categories.dtype if expand else object 

1079 else: 

1080 dtype = object if self._data.dtype == object else None 

1081 return self._wrap_result( 

1082 result, expand=expand, returns_string=expand, dtype=dtype 

1083 ) 

1084 

1085 @forbid_nonstring_types(["bytes"]) 

1086 def partition(self, sep: str = " ", expand: bool = True): 

1087 """ 

1088 Split the string at the first occurrence of `sep`. 

1089 

1090 This method splits the string at the first occurrence of `sep`, 

1091 and returns 3 elements containing the part before the separator, 

1092 the separator itself, and the part after the separator. 

1093 If the separator is not found, return 3 elements containing the string itself, 

1094 followed by two empty strings. 

1095 

1096 Parameters 

1097 ---------- 

1098 sep : str, default whitespace 

1099 String to split on. 

1100 expand : bool, default True 

1101 If True, return DataFrame/MultiIndex expanding dimensionality. 

1102 If False, return Series/Index. 

1103 

1104 Returns 

1105 ------- 

1106 DataFrame/MultiIndex or Series/Index of objects 

1107 Returns appropriate type based on `expand` parameter with strings 

1108 split based on the `sep` parameter. 

1109 

1110 See Also 

1111 -------- 

1112 rpartition : Split the string at the last occurrence of `sep`. 

1113 Series.str.split : Split strings around given separators. 

1114 str.partition : Standard library version. 

1115 

1116 Examples 

1117 -------- 

1118 >>> s = pd.Series(["Linda van der Berg", "George Pitt-Rivers"]) 

1119 >>> s 

1120 0 Linda van der Berg 

1121 1 George Pitt-Rivers 

1122 dtype: str 

1123 

1124 >>> s.str.partition() 

1125 0 1 2 

1126 0 Linda van der Berg 

1127 1 George Pitt-Rivers 

1128 

1129 To partition by the last space instead of the first one: 

1130 

1131 >>> s.str.rpartition() 

1132 0 1 2 

1133 0 Linda van der Berg 

1134 1 George Pitt-Rivers 

1135 

1136 To partition by something different than a space: 

1137 

1138 >>> s.str.partition("-") 

1139 0 1 2 

1140 0 Linda van der Berg 

1141 1 George Pitt - Rivers 

1142 

1143 To return a Series containing tuples instead of a DataFrame: 

1144 

1145 >>> s.str.partition("-", expand=False) 

1146 0 (Linda van der Berg, , ) 

1147 1 (George Pitt, -, Rivers) 

1148 dtype: object 

1149 

1150 Also available on indices: 

1151 

1152 >>> idx = pd.Index(["X 123", "Y 999"]) 

1153 >>> idx 

1154 Index(['X 123', 'Y 999'], dtype='str') 

1155 

1156 Which will create a MultiIndex: 

1157 

1158 >>> idx.str.partition() 

1159 MultiIndex([('X', ' ', '123'), 

1160 ('Y', ' ', '999')], 

1161 ) 

1162 

1163 Or an index with tuples with ``expand=False``: 

1164 

1165 >>> idx.str.partition(expand=False) 

1166 Index([('X', ' ', '123'), ('Y', ' ', '999')], dtype='object') 

1167 """ 

1168 result = self._data.array._str_partition(sep, expand) 

1169 if self._data.dtype == "category": 

1170 dtype = self._data.dtype.categories.dtype if expand else object 

1171 else: 

1172 dtype = object if self._data.dtype == object else None 

1173 return self._wrap_result( 

1174 result, expand=expand, returns_string=expand, dtype=dtype 

1175 ) 

1176 

1177 @forbid_nonstring_types(["bytes"]) 

1178 def rpartition(self, sep: str = " ", expand: bool = True): 

1179 """ 

1180 Split the string at the last occurrence of `sep`. 

1181 

1182 This method splits the string at the last occurrence of `sep`, 

1183 and returns 3 elements containing the part before the separator, 

1184 the separator itself, and the part after the separator. 

1185 If the separator is not found, return 3 elements containing two empty strings, 

1186 followed by the string itself. 

1187 

1188 Parameters 

1189 ---------- 

1190 sep : str, default " " 

1191 String to split on. 

1192 expand : bool, default True 

1193 If True, return DataFrame/MultiIndex expanding dimensionality. 

1194 If False, return Series/Index. 

1195 

1196 Returns 

1197 ------- 

1198 DataFrame/MultiIndex or Series/Index of objects 

1199 Returns appropriate type based on `expand` parameter with strings 

1200 split based on the `sep` parameter. 

1201 

1202 See Also 

1203 -------- 

1204 partition : Split the string at the first occurrence of `sep`. 

1205 Series.str.split : Split strings around given separators. 

1206 str.partition : Standard library version. 

1207 

1208 Examples 

1209 -------- 

1210 >>> s = pd.Series(["Linda van der Berg", "George Pitt-Rivers"]) 

1211 >>> s 

1212 0 Linda van der Berg 

1213 1 George Pitt-Rivers 

1214 dtype: str 

1215 

1216 >>> s.str.partition() 

1217 0 1 2 

1218 0 Linda van der Berg 

1219 1 George Pitt-Rivers 

1220 

1221 To partition by the last space instead of the first one: 

1222 

1223 >>> s.str.rpartition() 

1224 0 1 2 

1225 0 Linda van der Berg 

1226 1 George Pitt-Rivers 

1227 

1228 To partition by something different than a space: 

1229 

1230 >>> s.str.partition("-") 

1231 0 1 2 

1232 0 Linda van der Berg 

1233 1 George Pitt - Rivers 

1234 

1235 To return a Series containing tuples instead of a DataFrame: 

1236 

1237 >>> s.str.partition("-", expand=False) 

1238 0 (Linda van der Berg, , ) 

1239 1 (George Pitt, -, Rivers) 

1240 dtype: object 

1241 

1242 Also available on indices: 

1243 

1244 >>> idx = pd.Index(["X 123", "Y 999"]) 

1245 >>> idx 

1246 Index(['X 123', 'Y 999'], dtype='str') 

1247 

1248 Which will create a MultiIndex: 

1249 

1250 >>> idx.str.partition() 

1251 MultiIndex([('X', ' ', '123'), 

1252 ('Y', ' ', '999')], 

1253 ) 

1254 

1255 Or an index with tuples with ``expand=False``: 

1256 

1257 >>> idx.str.partition(expand=False) 

1258 Index([('X', ' ', '123'), ('Y', ' ', '999')], dtype='object') 

1259 """ 

1260 result = self._data.array._str_rpartition(sep, expand) 

1261 if self._data.dtype == "category": 

1262 dtype = self._data.dtype.categories.dtype if expand else object 

1263 else: 

1264 dtype = object if self._data.dtype == object else None 

1265 return self._wrap_result( 

1266 result, expand=expand, returns_string=expand, dtype=dtype 

1267 ) 

1268 

1269 def get(self, i): 

1270 """ 

1271 Extract element from each component at specified position or with specified key. 

1272 

1273 Extract element from lists, tuples, dict, or strings in each element in the 

1274 Series/Index. 

1275 

1276 Parameters 

1277 ---------- 

1278 i : int or hashable dict label 

1279 Position or key of element to extract. 

1280 

1281 Returns 

1282 ------- 

1283 Series or Index 

1284 Series or Index where each value is the extracted element from 

1285 the corresponding input component. 

1286 

1287 See Also 

1288 -------- 

1289 Series.str.extract : Extract capture groups in the regex as columns 

1290 in a DataFrame. 

1291 

1292 Examples 

1293 -------- 

1294 >>> s = pd.Series( 

1295 ... [ 

1296 ... "String", 

1297 ... (1, 2, 3), 

1298 ... ["a", "b", "c"], 

1299 ... 123, 

1300 ... -456, 

1301 ... {1: "Hello", "2": "World"}, 

1302 ... ] 

1303 ... ) 

1304 >>> s 

1305 0 String 

1306 1 (1, 2, 3) 

1307 2 [a, b, c] 

1308 3 123 

1309 4 -456 

1310 5 {1: 'Hello', '2': 'World'} 

1311 dtype: object 

1312 

1313 >>> s.str.get(1) 

1314 0 t 

1315 1 2 

1316 2 b 

1317 3 NaN 

1318 4 NaN 

1319 5 Hello 

1320 dtype: object 

1321 

1322 >>> s.str.get(-1) 

1323 0 g 

1324 1 3 

1325 2 c 

1326 3 NaN 

1327 4 NaN 

1328 5 None 

1329 dtype: object 

1330 

1331 Return element with given key 

1332 

1333 >>> s = pd.Series( 

1334 ... [ 

1335 ... {"name": "Hello", "value": "World"}, 

1336 ... {"name": "Goodbye", "value": "Planet"}, 

1337 ... ] 

1338 ... ) 

1339 >>> s.str.get("name") 

1340 0 Hello 

1341 1 Goodbye 

1342 dtype: object 

1343 """ 

1344 result = self._data.array._str_get(i) 

1345 return self._wrap_result(result) 

1346 

1347 @forbid_nonstring_types(["bytes"]) 

1348 def join(self, sep: str): 

1349 """ 

1350 Join lists contained as elements in the Series/Index with passed delimiter. 

1351 

1352 If the elements of a Series are lists themselves, join the content of these 

1353 lists using the delimiter passed to the function. 

1354 This function is an equivalent to :meth:`str.join`. 

1355 

1356 Parameters 

1357 ---------- 

1358 sep : str 

1359 Delimiter to use between list entries. 

1360 

1361 Returns 

1362 ------- 

1363 Series/Index: object 

1364 The list entries concatenated by intervening occurrences of the 

1365 delimiter. 

1366 

1367 Raises 

1368 ------ 

1369 AttributeError 

1370 If the supplied Series contains neither strings nor lists. 

1371 

1372 See Also 

1373 -------- 

1374 str.join : Standard library version of this method. 

1375 Series.str.split : Split strings around given separator/delimiter. 

1376 

1377 Notes 

1378 ----- 

1379 If any of the list items is not a string object, the result of the join 

1380 will be `NaN`. 

1381 

1382 Examples 

1383 -------- 

1384 Example with a list that contains non-string elements. 

1385 

1386 >>> s = pd.Series( 

1387 ... [ 

1388 ... ["lion", "elephant", "zebra"], 

1389 ... [1.1, 2.2, 3.3], 

1390 ... ["cat", np.nan, "dog"], 

1391 ... ["cow", 4.5, "goat"], 

1392 ... ["duck", ["swan", "fish"], "guppy"], 

1393 ... ] 

1394 ... ) 

1395 >>> s 

1396 0 [lion, elephant, zebra] 

1397 1 [1.1, 2.2, 3.3] 

1398 2 [cat, nan, dog] 

1399 3 [cow, 4.5, goat] 

1400 4 [duck, [swan, fish], guppy] 

1401 dtype: object 

1402 

1403 Join all lists using a '-'. The lists containing object(s) of types other 

1404 than str will produce a NaN. 

1405 

1406 >>> s.str.join("-") 

1407 0 lion-elephant-zebra 

1408 1 NaN 

1409 2 NaN 

1410 3 NaN 

1411 4 NaN 

1412 dtype: object 

1413 """ 

1414 result = self._data.array._str_join(sep) 

1415 return self._wrap_result(result) 

1416 

1417 @forbid_nonstring_types(["bytes"]) 

1418 def contains( 

1419 self, 

1420 pat, 

1421 case: bool = True, 

1422 flags: int = 0, 

1423 na=lib.no_default, 

1424 regex: bool = True, 

1425 ): 

1426 r""" 

1427 Test if pattern or regex is contained within a string of a Series or Index. 

1428 

1429 Return boolean Series or Index based on whether a given pattern or regex is 

1430 contained within a string of a Series or Index. 

1431 

1432 Parameters 

1433 ---------- 

1434 pat : str 

1435 Character sequence or regular expression. 

1436 case : bool, default True 

1437 If True, case sensitive. 

1438 flags : int, default 0 (no flags) 

1439 Flags to pass through to the re module, e.g. re.IGNORECASE. 

1440 na : scalar, optional 

1441 Fill value for missing values. The default depends on dtype of the 

1442 array. For the ``"str"`` dtype, ``False`` is used. For object 

1443 dtype, ``numpy.nan`` is used. For the nullable ``StringDtype``, 

1444 ``pandas.NA`` is used. 

1445 regex : bool, default True 

1446 If True, assumes the pat is a regular expression. 

1447 

1448 If False, treats the pat as a literal string. 

1449 

1450 Returns 

1451 ------- 

1452 Series or Index of boolean values 

1453 A Series or Index of boolean values indicating whether the 

1454 given pattern is contained within the string of each element 

1455 of the Series or Index. 

1456 

1457 See Also 

1458 -------- 

1459 match : Analogous, but stricter, relying on re.match instead of re.search. 

1460 Series.str.startswith : Test if the start of each string element matches a 

1461 pattern. 

1462 Series.str.endswith : Same as startswith, but tests the end of string. 

1463 

1464 Examples 

1465 -------- 

1466 Returning a Series of booleans using only a literal pattern. 

1467 

1468 >>> s1 = pd.Series(["Mouse", "dog", "house and parrot", "23", np.nan]) 

1469 >>> s1.str.contains("og", regex=False) 

1470 0 False 

1471 1 True 

1472 2 False 

1473 3 False 

1474 4 False 

1475 dtype: bool 

1476 

1477 Returning an Index of booleans using only a literal pattern. 

1478 

1479 >>> ind = pd.Index(["Mouse", "dog", "house and parrot", "23.0", np.nan]) 

1480 >>> ind.str.contains("23", regex=False) 

1481 array([False, False, False, True, False]) 

1482 

1483 Specifying case sensitivity using `case`. 

1484 

1485 >>> s1.str.contains("oG", case=True, regex=True) 

1486 0 False 

1487 1 False 

1488 2 False 

1489 3 False 

1490 4 False 

1491 dtype: bool 

1492 

1493 Returning 'house' or 'dog' when either expression occurs in a string. 

1494 

1495 >>> s1.str.contains("house|dog", regex=True) 

1496 0 False 

1497 1 True 

1498 2 True 

1499 3 False 

1500 4 False 

1501 dtype: bool 

1502 

1503 Ignoring case sensitivity using `flags` with regex. 

1504 

1505 >>> import re 

1506 >>> s1.str.contains("PARROT", flags=re.IGNORECASE, regex=True) 

1507 0 False 

1508 1 False 

1509 2 True 

1510 3 False 

1511 4 False 

1512 dtype: bool 

1513 

1514 Returning any digit using regular expression. 

1515 

1516 >>> s1.str.contains("\\d", regex=True) 

1517 0 False 

1518 1 False 

1519 2 False 

1520 3 True 

1521 4 False 

1522 dtype: bool 

1523 

1524 Ensure `pat` is a not a literal pattern when `regex` is set to True. 

1525 Note in the following example one might expect only `s2[1]` and `s2[3]` to 

1526 return `True`. However, '.0' as a regex matches any character 

1527 followed by a 0. 

1528 

1529 >>> s2 = pd.Series(["40", "40.0", "41", "41.0", "35"]) 

1530 >>> s2.str.contains(".0", regex=True) 

1531 0 True 

1532 1 True 

1533 2 False 

1534 3 True 

1535 4 False 

1536 dtype: bool 

1537 """ 

1538 if regex: 

1539 try: 

1540 has_groups = re.compile(pat).groups 

1541 except re.error: 

1542 has_groups = False 

1543 if has_groups: 

1544 warnings.warn( 

1545 "This pattern is interpreted as a regular expression, and has " 

1546 "match groups. To actually get the groups, use str.extract.", 

1547 UserWarning, 

1548 stacklevel=find_stack_level(), 

1549 ) 

1550 

1551 result = self._data.array._str_contains(pat, case, flags, na, regex) 

1552 return self._wrap_result(result, fill_value=na, returns_string=False) 

1553 

1554 @forbid_nonstring_types(["bytes"]) 

1555 def match( 

1556 self, 

1557 pat: str | re.Pattern, 

1558 case: bool | lib.NoDefault = lib.no_default, 

1559 flags: int | lib.NoDefault = lib.no_default, 

1560 na=lib.no_default, 

1561 ): 

1562 """ 

1563 Determine if each string starts with a match of a regular expression. 

1564 

1565 Determines whether each string in the Series or Index starts with a 

1566 match to a specified regular expression. This function is especially 

1567 useful for validating prefixes, such as ensuring that codes, tags, or 

1568 identifiers begin with a specific pattern. 

1569 

1570 Parameters 

1571 ---------- 

1572 pat : str or compiled regex 

1573 Character sequence or regular expression. 

1574 case : bool, default True 

1575 If True, case sensitive. 

1576 flags : int, default 0 (no flags) 

1577 Regex module flags, e.g. re.IGNORECASE. 

1578 na : scalar, optional 

1579 Fill value for missing values. The default depends on dtype of the 

1580 array. For the ``"str"`` dtype, ``False`` is used. For object 

1581 dtype, ``numpy.nan`` is used. For the nullable ``StringDtype``, 

1582 ``pandas.NA`` is used. 

1583 

1584 Returns 

1585 ------- 

1586 Series/Index/array of boolean values 

1587 A Series, Index, or array of boolean values indicating whether the start 

1588 of each string matches the pattern. The result will be of the same type 

1589 as the input. 

1590 

1591 See Also 

1592 -------- 

1593 fullmatch : Stricter matching that requires the entire string to match. 

1594 contains : Analogous, but less strict, relying on re.search instead of 

1595 re.match. 

1596 extract : Extract matched groups. 

1597 

1598 Examples 

1599 -------- 

1600 >>> ser = pd.Series(["horse", "eagle", "donkey"]) 

1601 >>> ser.str.match("e") 

1602 0 False 

1603 1 True 

1604 2 False 

1605 dtype: bool 

1606 """ 

1607 # Note: `case` must be resolved before we compile `pat` below, since 

1608 # compiling would make is_re(pat) True even for a user-passed string. 

1609 case_specified = case is not lib.no_default 

1610 

1611 if not case_specified: 

1612 if is_re(pat): 

1613 case = not bool(pat.flags & re.IGNORECASE) 

1614 elif flags is not lib.no_default: 

1615 case = not bool(flags & re.IGNORECASE) 

1616 else: 

1617 # Case-sensitive default 

1618 case = True 

1619 elif is_re(pat): 

1620 implicit_case = not bool(pat.flags & re.IGNORECASE) 

1621 if implicit_case != case: 

1622 # GH#62240 

1623 raise ValueError( 

1624 "Cannot both specify 'case' and pass a compiled regexp " 

1625 "object with conflicting case-sensitivity" 

1626 ) 

1627 

1628 if flags is not lib.no_default: 

1629 if case_specified and case and not is_re(pat) and flags & re.IGNORECASE: 

1630 raise ValueError( 

1631 "Cannot both specify case=True and pass 'flags' containing " 

1632 "re.IGNORECASE" 

1633 ) 

1634 if not case: 

1635 # Bake `case` into the flags so that it survives compilation. 

1636 flags |= re.IGNORECASE 

1637 if is_re(pat): 

1638 # Round-trip the requested flags through re.compile so the 

1639 # comparison accounts for the fixups it applies: the implicit 

1640 # re.U, and any inline "(?a)"/"(?i)" in the pattern itself. 

1641 if re.compile(pat.pattern, flags).flags != pat.flags: 

1642 raise ValueError( 

1643 "Cannot both specify 'flags' and pass a compiled regexp " 

1644 "object with conflicting flags" 

1645 ) 

1646 elif flags & ~(re.IGNORECASE | re.UNICODE): 

1647 # Only pre-compile when `flags` carries something `case` cannot. 

1648 # Leaving `pat` a str otherwise keeps `flags=0` equivalent to 

1649 # omitting `flags`, so patterns using RE2 syntax that `re` 

1650 # rejects still reach the pyarrow kernels. GH#63108 

1651 pat = re.compile(pat, flags=flags) 

1652 # Any `flags` are now carried by `case` or baked into `pat`, so set 

1653 # flags=0 to ensure that when we call re.compile(pat, flags=flags) 

1654 # downstream the constructor does not raise. 

1655 flags = 0 

1656 

1657 result = self._data.array._str_match(pat, case=case, flags=flags, na=na) 

1658 return self._wrap_result(result, fill_value=na, returns_string=False) 

1659 

1660 @forbid_nonstring_types(["bytes"]) 

1661 def fullmatch(self, pat, case: bool = True, flags: int = 0, na=lib.no_default): 

1662 """ 

1663 Determine if each string entirely matches a regular expression. 

1664 

1665 Checks if each string in the Series or Index fully matches the 

1666 specified regular expression pattern. This function is useful when the 

1667 requirement is for an entire string to conform to a pattern, such as 

1668 validating formats like phone numbers or email addresses. 

1669 

1670 Parameters 

1671 ---------- 

1672 pat : str 

1673 Character sequence or regular expression. 

1674 case : bool, default True 

1675 If True, case sensitive. 

1676 flags : int, default 0 (no flags) 

1677 Regex module flags, e.g. re.IGNORECASE. 

1678 na : scalar, optional 

1679 Fill value for missing values. The default depends on dtype of the 

1680 array. For the ``"str"`` dtype, ``False`` is used. For object 

1681 dtype, ``numpy.nan`` is used. For the nullable ``StringDtype``, 

1682 ``pandas.NA`` is used. 

1683 

1684 Returns 

1685 ------- 

1686 Series/Index/array of boolean values 

1687 The function returns a Series, Index, or array of boolean values, 

1688 where True indicates that the entire string matches the regular 

1689 expression pattern and False indicates that it does not. 

1690 

1691 See Also 

1692 -------- 

1693 match : Similar, but also returns `True` when only a *prefix* of the string 

1694 matches the regular expression. 

1695 extract : Extract matched groups. 

1696 

1697 Examples 

1698 -------- 

1699 >>> ser = pd.Series(["cat", "duck", "dove"]) 

1700 >>> ser.str.fullmatch(r"d.+") 

1701 0 False 

1702 1 True 

1703 2 True 

1704 dtype: bool 

1705 """ 

1706 result = self._data.array._str_fullmatch(pat, case=case, flags=flags, na=na) 

1707 return self._wrap_result(result, fill_value=na, returns_string=False) 

1708 

1709 @forbid_nonstring_types(["bytes"]) 

1710 def replace( 

1711 self, 

1712 pat: str | re.Pattern | dict, 

1713 repl: str | Callable | None = None, 

1714 n: int = -1, 

1715 case: bool | None = None, 

1716 flags: int = 0, 

1717 regex: bool = False, 

1718 ): 

1719 r""" 

1720 Replace each occurrence of pattern/regex in the Series/Index. 

1721 

1722 Equivalent to :meth:`str.replace` or :func:`re.sub`, depending on 

1723 the regex value. 

1724 

1725 Parameters 

1726 ---------- 

1727 pat : str, compiled regex, or a dict 

1728 String can be a character sequence or regular expression. 

1729 Dictionary contains <key : value> pairs of strings to be replaced 

1730 along with the updated value. 

1731 repl : str or callable 

1732 Replacement string or a callable. The callable is passed the regex 

1733 match object and must return a replacement string to be used. 

1734 Must have a value of None if `pat` is a dict 

1735 See :func:`re.sub`. 

1736 n : int, default -1 (all) 

1737 Number of replacements to make from start. 

1738 case : bool, default None 

1739 Determines if replace is case sensitive: 

1740 

1741 - If True, case sensitive (the default if `pat` is a string) 

1742 - Set to False for case insensitive 

1743 - Cannot be set if `pat` is a compiled regex. 

1744 

1745 flags : int, default 0 (no flags) 

1746 Regex module flags, e.g. re.IGNORECASE. Cannot be set if `pat` is a compiled 

1747 regex. 

1748 regex : bool, default False 

1749 Determines if the passed-in pattern is a regular expression: 

1750 

1751 - If True, assumes the passed-in pattern is a regular expression. 

1752 - If False, treats the pattern as a literal string 

1753 - Cannot be set to False if `pat` is a compiled regex or `repl` is 

1754 a callable. 

1755 

1756 Returns 

1757 ------- 

1758 Series or Index of object 

1759 A copy of the object with all matching occurrences of `pat` replaced by 

1760 `repl`. 

1761 

1762 Raises 

1763 ------ 

1764 ValueError 

1765 * if `regex` is False and `repl` is a callable or `pat` is a compiled 

1766 regex 

1767 * if `pat` is a compiled regex and `case` or `flags` is set 

1768 * if `pat` is a dictionary and `repl` is not None. 

1769 

1770 See Also 

1771 -------- 

1772 Series.str.replace : Method to replace occurrences of a substring with another 

1773 substring. 

1774 Series.str.extract : Extract substrings using a regular expression. 

1775 Series.str.findall : Find all occurrences of a pattern or regex in each string. 

1776 Series.str.split : Split each string by a specified delimiter or pattern. 

1777 

1778 Notes 

1779 ----- 

1780 When `pat` is a compiled regex, all flags should be included in the 

1781 compiled regex. Use of `case`, `flags`, or `regex=False` with a compiled 

1782 regex will raise an error. 

1783 

1784 Examples 

1785 -------- 

1786 When `pat` is a dictionary, every key in `pat` is replaced 

1787 with its corresponding value: 

1788 

1789 >>> pd.Series(["A", "B", np.nan]).str.replace(pat={"A": "a", "B": "b"}) 

1790 0 a 

1791 1 b 

1792 2 NaN 

1793 dtype: str 

1794 

1795 When `pat` is a string and `regex` is True, the given `pat` 

1796 is compiled as a regex. When `repl` is a string, it replaces matching 

1797 regex patterns as with :meth:`re.sub`. NaN value(s) in the Series are 

1798 left as is: 

1799 

1800 >>> pd.Series(["foo", "fuz", np.nan]).str.replace("f.", "ba", regex=True) 

1801 0 bao 

1802 1 baz 

1803 2 NaN 

1804 dtype: str 

1805 

1806 When `pat` is a string and `regex` is False, every `pat` is replaced with 

1807 `repl` as with :meth:`str.replace`: 

1808 

1809 >>> pd.Series(["f.o", "fuz", np.nan]).str.replace("f.", "ba", regex=False) 

1810 0 bao 

1811 1 fuz 

1812 2 NaN 

1813 dtype: str 

1814 

1815 When `repl` is a callable, it is called on every `pat` using 

1816 :func:`re.sub`. The callable should expect one positional argument 

1817 (a regex object) and return a string. 

1818 

1819 To get the idea: 

1820 

1821 >>> pd.Series(["foo", "fuz", np.nan]).str.replace("f", repr, regex=True) 

1822 0 <re.Match object; span=(0, 1), match='f'>oo 

1823 1 <re.Match object; span=(0, 1), match='f'>uz 

1824 2 NaN 

1825 dtype: str 

1826 

1827 Reverse every lowercase alphabetic word: 

1828 

1829 >>> repl = lambda m: m.group(0)[::-1] 

1830 >>> ser = pd.Series(["foo 123", "bar baz", np.nan]) 

1831 >>> ser.str.replace(r"[a-z]+", repl, regex=True) 

1832 0 oof 123 

1833 1 rab zab 

1834 2 NaN 

1835 dtype: str 

1836 

1837 Using regex groups (extract second group and swap case): 

1838 

1839 >>> pat = r"(?P<one>\w+) (?P<two>\w+) (?P<three>\w+)" 

1840 >>> repl = lambda m: m.group("two").swapcase() 

1841 >>> ser = pd.Series(["One Two Three", "Foo Bar Baz"]) 

1842 >>> ser.str.replace(pat, repl, regex=True) 

1843 0 tWO 

1844 1 bAR 

1845 dtype: str 

1846 

1847 Using a compiled regex with flags 

1848 

1849 >>> import re 

1850 >>> regex_pat = re.compile(r"FUZ", flags=re.IGNORECASE) 

1851 >>> pd.Series(["foo", "fuz", np.nan]).str.replace(regex_pat, "bar", regex=True) 

1852 0 foo 

1853 1 bar 

1854 2 NaN 

1855 dtype: str 

1856 """ 

1857 if isinstance(pat, dict) and repl is not None: 

1858 raise ValueError("repl cannot be used when pat is a dictionary") 

1859 

1860 # Check whether repl is valid (GH 13438, GH 15055) 

1861 if not isinstance(pat, dict) and not (isinstance(repl, str) or callable(repl)): 

1862 raise TypeError("repl must be a string or callable") 

1863 

1864 is_compiled_re = is_re(pat) 

1865 if regex or regex is None: 

1866 if is_compiled_re and (case is not None or flags != 0): 

1867 raise ValueError( 

1868 "case and flags cannot be set when pat is a compiled regex" 

1869 ) 

1870 

1871 elif is_compiled_re: 

1872 raise ValueError( 

1873 "Cannot use a compiled regex as replacement pattern with regex=False" 

1874 ) 

1875 elif callable(repl): 

1876 raise ValueError("Cannot use a callable replacement when regex=False") 

1877 

1878 if case is None: 

1879 case = True 

1880 

1881 res_output = self._data 

1882 if not isinstance(pat, dict): 

1883 pat = {pat: repl} 

1884 

1885 for key, value in pat.items(): 

1886 result = res_output.array._str_replace( 

1887 key, value, n=n, case=case, flags=flags, regex=regex 

1888 ) 

1889 res_output = self._wrap_result(result) 

1890 

1891 return res_output 

1892 

1893 @forbid_nonstring_types(["bytes"]) 

1894 def repeat(self, repeats): 

1895 """ 

1896 Duplicate each string in the Series or Index. 

1897 

1898 Duplicates each string in the Series or Index, either by applying the 

1899 same repeat count to all elements or by using different repeat values 

1900 for each element. 

1901 

1902 Parameters 

1903 ---------- 

1904 repeats : int or sequence of int 

1905 Same value for all (int) or different value per (sequence). 

1906 

1907 Returns 

1908 ------- 

1909 Series or pandas.Index 

1910 Series or Index of repeated string objects specified by 

1911 input parameter repeats. 

1912 

1913 See Also 

1914 -------- 

1915 Series.str.lower : Convert all characters in each string to lowercase. 

1916 Series.str.upper : Convert all characters in each string to uppercase. 

1917 Series.str.title : Convert each string to title case (capitalizing the first 

1918 letter of each word). 

1919 Series.str.strip : Remove leading and trailing whitespace from each string. 

1920 Series.str.replace : Replace occurrences of a substring with another substring 

1921 in each string. 

1922 Series.str.ljust : Left-justify each string in the Series/Index by padding with 

1923 a specified character. 

1924 Series.str.rjust : Right-justify each string in the Series/Index by padding with 

1925 a specified character. 

1926 

1927 Examples 

1928 -------- 

1929 >>> s = pd.Series(["a", "b", "c"]) 

1930 >>> s 

1931 0 a 

1932 1 b 

1933 2 c 

1934 dtype: str 

1935 

1936 Single int repeats string in Series 

1937 

1938 >>> s.str.repeat(repeats=2) 

1939 0 aa 

1940 1 bb 

1941 2 cc 

1942 dtype: str 

1943 

1944 Sequence of int repeats corresponding string in Series 

1945 

1946 >>> s.str.repeat(repeats=[1, 2, 3]) 

1947 0 a 

1948 1 bb 

1949 2 ccc 

1950 dtype: str 

1951 """ 

1952 result = self._data.array._str_repeat(repeats) 

1953 return self._wrap_result(result) 

1954 

1955 @forbid_nonstring_types(["bytes"]) 

1956 def pad( 

1957 self, 

1958 width: int, 

1959 side: Literal["left", "right", "both"] = "left", 

1960 fillchar: str = " ", 

1961 ): 

1962 """ 

1963 Pad strings in the Series/Index up to width. 

1964 

1965 This function pads strings in a Series or Index to a specified width, 

1966 filling the extra space with a character of your choice. It provides 

1967 flexibility in positioning the padding, allowing it to be added to the 

1968 left, right, or both sides. This is useful for formatting strings to 

1969 align text or ensure consistent string lengths in data processing. 

1970 

1971 Parameters 

1972 ---------- 

1973 width : int 

1974 Minimum width of resulting string; additional characters will be filled 

1975 with character defined in `fillchar`. 

1976 side : {'left', 'right', 'both'}, default 'left' 

1977 Side from which to fill resulting string. 

1978 fillchar : str, default ' ' 

1979 Additional character for filling, default is whitespace. 

1980 

1981 Returns 

1982 ------- 

1983 Series or Index of object 

1984 Returns Series or Index with minimum number of char in object. 

1985 

1986 See Also 

1987 -------- 

1988 Series.str.rjust : Fills the left side of strings with an arbitrary 

1989 character. Equivalent to ``Series.str.pad(side='left')``. 

1990 Series.str.ljust : Fills the right side of strings with an arbitrary 

1991 character. Equivalent to ``Series.str.pad(side='right')``. 

1992 Series.str.center : Fills both sides of strings with an arbitrary 

1993 character. Equivalent to ``Series.str.pad(side='both')``. 

1994 Series.str.zfill : Pad strings in the Series/Index by prepending '0' 

1995 character. Equivalent to ``Series.str.pad(side='left', fillchar='0')``. 

1996 

1997 Examples 

1998 -------- 

1999 >>> s = pd.Series(["caribou", "tiger"]) 

2000 >>> s 

2001 0 caribou 

2002 1 tiger 

2003 dtype: str 

2004 

2005 >>> s.str.pad(width=10) 

2006 0 caribou 

2007 1 tiger 

2008 dtype: str 

2009 

2010 >>> s.str.pad(width=10, side="right", fillchar="-") 

2011 0 caribou--- 

2012 1 tiger----- 

2013 dtype: str 

2014 

2015 >>> s.str.pad(width=10, side="both", fillchar="-") 

2016 0 -caribou-- 

2017 1 --tiger--- 

2018 dtype: str 

2019 """ 

2020 if not isinstance(fillchar, str): 

2021 msg = f"fillchar must be a character, not {type(fillchar).__name__}" 

2022 raise TypeError(msg) 

2023 

2024 if len(fillchar) != 1: 

2025 raise TypeError("fillchar must be a character, not str") 

2026 

2027 if not is_integer(width): 

2028 msg = f"width must be of integer type, not {type(width).__name__}" 

2029 raise TypeError(msg) 

2030 

2031 result = self._data.array._str_pad(width, side=side, fillchar=fillchar) 

2032 return self._wrap_result(result) 

2033 

2034 @forbid_nonstring_types(["bytes"]) 

2035 def center(self, width: int, fillchar: str = " "): 

2036 """ 

2037 Pad left and right side of strings in the Series/Index. 

2038 

2039 Equivalent to :meth:`str.center`. 

2040 

2041 Parameters 

2042 ---------- 

2043 width : int 

2044 Minimum width of resulting string; additional characters will be filled 

2045 with ``fillchar``. 

2046 fillchar : str 

2047 Additional character for filling, default is whitespace. 

2048 

2049 Returns 

2050 ------- 

2051 Series/Index of objects. 

2052 A Series or Index where the strings are modified by :meth:`str.center`. 

2053 

2054 See Also 

2055 -------- 

2056 Series.str.rjust : Fills the left side of strings with an arbitrary 

2057 character. 

2058 Series.str.ljust : Fills the right side of strings with an arbitrary 

2059 character. 

2060 Series.str.center : Fills both sides of strings with an arbitrary 

2061 character. 

2062 Series.str.zfill : Pad strings in the Series/Index by prepending '0' 

2063 character. 

2064 

2065 Examples 

2066 -------- 

2067 For Series.str.center: 

2068 

2069 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2070 >>> ser.str.center(8, fillchar=".") 

2071 0 ..dog... 

2072 1 ..bird.. 

2073 2 .mouse.. 

2074 dtype: str 

2075 

2076 For Series.str.ljust: 

2077 

2078 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2079 >>> ser.str.ljust(8, fillchar=".") 

2080 0 dog..... 

2081 1 bird.... 

2082 2 mouse... 

2083 dtype: str 

2084 

2085 For Series.str.rjust: 

2086 

2087 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2088 >>> ser.str.rjust(8, fillchar=".") 

2089 0 .....dog 

2090 1 ....bird 

2091 2 ...mouse 

2092 dtype: str 

2093 """ 

2094 return self.pad(width, side="both", fillchar=fillchar) 

2095 

2096 @forbid_nonstring_types(["bytes"]) 

2097 def ljust(self, width: int, fillchar: str = " "): 

2098 """ 

2099 Pad right side of strings in the Series/Index. 

2100 

2101 Equivalent to :meth:`str.ljust`. 

2102 

2103 Parameters 

2104 ---------- 

2105 width : int 

2106 Minimum width of resulting string; additional characters will be filled 

2107 with ``fillchar``. 

2108 fillchar : str 

2109 Additional character for filling, default is whitespace. 

2110 

2111 Returns 

2112 ------- 

2113 Series/Index of objects. 

2114 A Series or Index where the strings are modified by :meth:`str.ljust`. 

2115 

2116 See Also 

2117 -------- 

2118 Series.str.rjust : Fills the left side of strings with an arbitrary 

2119 character. 

2120 Series.str.ljust : Fills the right side of strings with an arbitrary 

2121 character. 

2122 Series.str.center : Fills both sides of strings with an arbitrary 

2123 character. 

2124 Series.str.zfill : Pad strings in the Series/Index by prepending '0' 

2125 character. 

2126 

2127 Examples 

2128 -------- 

2129 For Series.str.center: 

2130 

2131 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2132 >>> ser.str.center(8, fillchar=".") 

2133 0 ..dog... 

2134 1 ..bird.. 

2135 2 .mouse.. 

2136 dtype: str 

2137 

2138 For Series.str.ljust: 

2139 

2140 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2141 >>> ser.str.ljust(8, fillchar=".") 

2142 0 dog..... 

2143 1 bird.... 

2144 2 mouse... 

2145 dtype: str 

2146 

2147 For Series.str.rjust: 

2148 

2149 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2150 >>> ser.str.rjust(8, fillchar=".") 

2151 0 .....dog 

2152 1 ....bird 

2153 2 ...mouse 

2154 dtype: str 

2155 """ 

2156 return self.pad(width, side="right", fillchar=fillchar) 

2157 

2158 @forbid_nonstring_types(["bytes"]) 

2159 def rjust(self, width: int, fillchar: str = " "): 

2160 """ 

2161 Pad left side of strings in the Series/Index. 

2162 

2163 Equivalent to :meth:`str.rjust`. 

2164 

2165 Parameters 

2166 ---------- 

2167 width : int 

2168 Minimum width of resulting string; additional characters will be filled 

2169 with ``fillchar``. 

2170 fillchar : str 

2171 Additional character for filling, default is whitespace. 

2172 

2173 Returns 

2174 ------- 

2175 Series/Index of objects. 

2176 A Series or Index where the strings are modified by :meth:`str.rjust`. 

2177 

2178 See Also 

2179 -------- 

2180 Series.str.rjust : Fills the left side of strings with an arbitrary 

2181 character. 

2182 Series.str.ljust : Fills the right side of strings with an arbitrary 

2183 character. 

2184 Series.str.center : Fills both sides of strings with an arbitrary 

2185 character. 

2186 Series.str.zfill : Pad strings in the Series/Index by prepending '0' 

2187 character. 

2188 

2189 Examples 

2190 -------- 

2191 For Series.str.center: 

2192 

2193 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2194 >>> ser.str.center(8, fillchar=".") 

2195 0 ..dog... 

2196 1 ..bird.. 

2197 2 .mouse.. 

2198 dtype: str 

2199 

2200 For Series.str.ljust: 

2201 

2202 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2203 >>> ser.str.ljust(8, fillchar=".") 

2204 0 dog..... 

2205 1 bird.... 

2206 2 mouse... 

2207 dtype: str 

2208 

2209 For Series.str.rjust: 

2210 

2211 >>> ser = pd.Series(["dog", "bird", "mouse"]) 

2212 >>> ser.str.rjust(8, fillchar=".") 

2213 0 .....dog 

2214 1 ....bird 

2215 2 ...mouse 

2216 dtype: str 

2217 """ 

2218 return self.pad(width, side="left", fillchar=fillchar) 

2219 

2220 @forbid_nonstring_types(["bytes"]) 

2221 def zfill(self, width: int): 

2222 """ 

2223 Pad strings in the Series/Index by prepending '0' characters. 

2224 

2225 Strings in the Series/Index are padded with '0' characters on the 

2226 left of the string to reach a total string length `width`. Strings 

2227 in the Series/Index with length greater or equal to `width` are 

2228 unchanged. 

2229 

2230 Parameters 

2231 ---------- 

2232 width : int 

2233 Minimum length of resulting string; strings with length less 

2234 than `width` be prepended with '0' characters. 

2235 

2236 Returns 

2237 ------- 

2238 Series/Index of objects. 

2239 A Series or Index where the strings are prepended with '0' characters. 

2240 

2241 See Also 

2242 -------- 

2243 Series.str.rjust : Fills the left side of strings with an arbitrary 

2244 character. 

2245 Series.str.ljust : Fills the right side of strings with an arbitrary 

2246 character. 

2247 Series.str.pad : Fills the specified sides of strings with an arbitrary 

2248 character. 

2249 Series.str.center : Fills both sides of strings with an arbitrary 

2250 character. 

2251 

2252 Notes 

2253 ----- 

2254 Follows the same rules as :meth:`str.zfill`: a leading sign character 

2255 ('+'/'-') is kept at the front of the string and the '0' padding is 

2256 inserted after it. 

2257 

2258 Examples 

2259 -------- 

2260 >>> s = pd.Series(["-1", "1", "1000", 10, np.nan]) 

2261 >>> s 

2262 0 -1 

2263 1 1 

2264 2 1000 

2265 3 10 

2266 4 NaN 

2267 dtype: object 

2268 

2269 Note that ``10`` and ``NaN`` are not strings, therefore they are 

2270 converted to ``NaN``. The minus sign in ``'-1'`` is kept at the front 

2271 of the string and the '0' padding is inserted after it, the same as 

2272 :meth:`str.zfill`. ``1000`` remains unchanged as it is longer than 

2273 `width`. 

2274 

2275 >>> s.str.zfill(3) 

2276 0 -01 

2277 1 001 

2278 2 1000 

2279 3 NaN 

2280 4 NaN 

2281 dtype: object 

2282 """ 

2283 if not is_integer(width): 

2284 msg = f"width must be of integer type, not {type(width).__name__}" 

2285 raise TypeError(msg) 

2286 

2287 result = self._data.array._str_zfill(width) 

2288 return self._wrap_result(result) 

2289 

2290 def slice(self, start=None, stop=None, step=None): 

2291 """ 

2292 Slice substrings from each element in the Series or Index. 

2293 

2294 Slicing substrings from strings in a Series or Index helps extract 

2295 specific portions of data, making it easier to analyze or manipulate 

2296 text. This is useful for tasks like parsing structured text fields or 

2297 isolating parts of strings with a consistent format. 

2298 

2299 Parameters 

2300 ---------- 

2301 start : int, optional 

2302 Start position for slice operation. 

2303 stop : int, optional 

2304 Stop position for slice operation. 

2305 step : int, optional 

2306 Step size for slice operation. 

2307 

2308 Returns 

2309 ------- 

2310 Series or Index of object 

2311 Series or Index from sliced substring from original string object. 

2312 

2313 See Also 

2314 -------- 

2315 Series.str.slice_replace : Replace a slice with a string. 

2316 Series.str.get : Return element at position. 

2317 Equivalent to `Series.str.slice(start=i, stop=i+1)` with `i` 

2318 being the position. 

2319 

2320 Examples 

2321 -------- 

2322 >>> s = pd.Series(["koala", "dog", "chameleon"]) 

2323 >>> s 

2324 0 koala 

2325 1 dog 

2326 2 chameleon 

2327 dtype: str 

2328 

2329 >>> s.str.slice(start=1) 

2330 0 oala 

2331 1 og 

2332 2 hameleon 

2333 dtype: str 

2334 

2335 >>> s.str.slice(start=-1) 

2336 0 a 

2337 1 g 

2338 2 n 

2339 dtype: str 

2340 

2341 >>> s.str.slice(stop=2) 

2342 0 ko 

2343 1 do 

2344 2 ch 

2345 dtype: str 

2346 

2347 >>> s.str.slice(step=2) 

2348 0 kaa 

2349 1 dg 

2350 2 caeen 

2351 dtype: str 

2352 

2353 >>> s.str.slice(start=0, stop=5, step=3) 

2354 0 kl 

2355 1 d 

2356 2 cm 

2357 dtype: str 

2358 

2359 Equivalent behaviour to: 

2360 

2361 >>> s.str[0:5:3] 

2362 0 kl 

2363 1 d 

2364 2 cm 

2365 dtype: str 

2366 """ 

2367 result = self._data.array._str_slice(start, stop, step) 

2368 return self._wrap_result(result) 

2369 

2370 @forbid_nonstring_types(["bytes"]) 

2371 def slice_replace(self, start=None, stop=None, repl=None): 

2372 """ 

2373 Replace a positional slice of a string with another value. 

2374 

2375 This function allows replacing specific parts of a string in a Series 

2376 or Index by specifying start and stop positions. It is useful for 

2377 modifying substrings in a controlled way, such as updating sections of 

2378 text based on their positions or patterns. 

2379 

2380 Parameters 

2381 ---------- 

2382 start : int, optional 

2383 Left index position to use for the slice. If not specified (None), 

2384 the slice is unbounded on the left, i.e. slice from the start 

2385 of the string. 

2386 stop : int, optional 

2387 Right index position to use for the slice. If not specified (None), 

2388 the slice is unbounded on the right, i.e. slice until the 

2389 end of the string. 

2390 repl : str, optional 

2391 String for replacement. If not specified (None), the sliced region 

2392 is replaced with an empty string. 

2393 

2394 Returns 

2395 ------- 

2396 Series or Index 

2397 Same type as the original object. 

2398 

2399 See Also 

2400 -------- 

2401 Series.str.slice : Just slicing without replacement. 

2402 

2403 Examples 

2404 -------- 

2405 >>> s = pd.Series(["a", "ab", "abc", "abdc", "abcde"]) 

2406 >>> s 

2407 0 a 

2408 1 ab 

2409 2 abc 

2410 3 abdc 

2411 4 abcde 

2412 dtype: str 

2413 

2414 Specify just `start`, meaning replace `start` until the end of the 

2415 string with `repl`. 

2416 

2417 >>> s.str.slice_replace(1, repl="X") 

2418 0 aX 

2419 1 aX 

2420 2 aX 

2421 3 aX 

2422 4 aX 

2423 dtype: str 

2424 

2425 Specify just `stop`, meaning the start of the string to `stop` is replaced 

2426 with `repl`, and the rest of the string is included. 

2427 

2428 >>> s.str.slice_replace(stop=2, repl="X") 

2429 0 X 

2430 1 X 

2431 2 Xc 

2432 3 Xdc 

2433 4 Xcde 

2434 dtype: str 

2435 

2436 Specify `start` and `stop`, meaning the slice from `start` to `stop` is 

2437 replaced with `repl`. Everything before or after `start` and `stop` is 

2438 included as is. 

2439 

2440 >>> s.str.slice_replace(start=1, stop=3, repl="X") 

2441 0 aX 

2442 1 aX 

2443 2 aX 

2444 3 aXc 

2445 4 aXde 

2446 dtype: str 

2447 """ 

2448 result = self._data.array._str_slice_replace(start, stop, repl) 

2449 return self._wrap_result(result) 

2450 

2451 def decode( 

2452 self, encoding, errors: str = "strict", dtype: str | DtypeObj | None = None 

2453 ): 

2454 """ 

2455 Decode character string in the Series/Index using indicated encoding. 

2456 

2457 Equivalent to :meth:`str.decode` in python2 and :meth:`bytes.decode` in 

2458 python3. 

2459 

2460 Parameters 

2461 ---------- 

2462 encoding : str 

2463 Specifies the encoding to be used. 

2464 errors : str, optional 

2465 Specifies the error handling scheme. 

2466 Possible values are those supported by :meth:`bytes.decode`. 

2467 dtype : str or dtype, optional 

2468 The dtype of the result. When not ``None``, must be either a string or 

2469 object dtype. When ``None``, the dtype of the result is determined by 

2470 ``pd.options.future.infer_string``. 

2471 

2472 .. versionadded:: 2.3.0 

2473 

2474 Returns 

2475 ------- 

2476 Series or Index 

2477 A Series or Index with decoded strings. 

2478 

2479 See Also 

2480 -------- 

2481 Series.str.encode : Encodes strings into bytes in a Series/Index. 

2482 

2483 Examples 

2484 -------- 

2485 For Series: 

2486 

2487 >>> ser = pd.Series([b"cow", b"123", b"()"]) 

2488 >>> ser.str.decode("ascii") 

2489 0 cow 

2490 1 123 

2491 2 () 

2492 dtype: str 

2493 """ 

2494 if dtype is not None and not is_string_dtype(dtype): 

2495 raise ValueError(f"dtype must be string or object, got {dtype=}") 

2496 if dtype is None and using_string_dtype(): 

2497 dtype = "str" 

2498 # TODO: Add a similar _bytes interface. 

2499 if encoding in _cpython_optimized_decoders: 

2500 # CPython optimized implementation 

2501 f = lambda x: x.decode(encoding, errors) 

2502 else: 

2503 decoder = codecs.getdecoder(encoding) 

2504 f = lambda x: decoder(x, errors)[0] 

2505 arr = self._data.array 

2506 result = arr._str_map(f) 

2507 return self._wrap_result(result, dtype=dtype) 

2508 

2509 @forbid_nonstring_types(["bytes"]) 

2510 def encode(self, encoding, errors: str = "strict"): 

2511 """ 

2512 Encode character string in the Series/Index using indicated encoding. 

2513 

2514 Equivalent to :meth:`str.encode`. 

2515 

2516 Parameters 

2517 ---------- 

2518 encoding : str 

2519 Specifies the encoding to be used. 

2520 errors : str, optional 

2521 Specifies the error handling scheme. 

2522 Possible values are those supported by :meth:`str.encode`. 

2523 

2524 Returns 

2525 ------- 

2526 Series/Index of objects 

2527 A Series or Index with strings encoded into bytes. 

2528 

2529 See Also 

2530 -------- 

2531 Series.str.decode : Decodes bytes into strings in a Series/Index. 

2532 

2533 Examples 

2534 -------- 

2535 >>> ser = pd.Series(["cow", "123", "()"]) 

2536 >>> ser.str.encode(encoding="ascii") 

2537 0 b'cow' 

2538 1 b'123' 

2539 2 b'()' 

2540 dtype: object 

2541 """ 

2542 result = self._data.array._str_encode(encoding, errors) 

2543 return self._wrap_result(result, returns_string=False) 

2544 

2545 @forbid_nonstring_types(["bytes"]) 

2546 def strip(self, to_strip=None): 

2547 """ 

2548 Remove leading and trailing characters. 

2549 

2550 Strip whitespaces (including newlines) or a set of specified characters 

2551 from each string in the Series/Index from left and right sides. 

2552 Replaces any non-strings in Series with NaNs. 

2553 Equivalent to :meth:`str.strip`. 

2554 

2555 Parameters 

2556 ---------- 

2557 to_strip : str or None, default None 

2558 Specifying the set of characters to be removed. 

2559 All combinations of this set of characters will be stripped. 

2560 If None then whitespaces are removed. 

2561 

2562 Returns 

2563 ------- 

2564 Series or Index of object 

2565 Series or Index with the strings being stripped from the left and 

2566 right sides. 

2567 

2568 See Also 

2569 -------- 

2570 Series.str.strip : Remove leading and trailing characters in Series/Index. 

2571 Series.str.lstrip : Remove leading characters in Series/Index. 

2572 Series.str.rstrip : Remove trailing characters in Series/Index. 

2573 

2574 Examples 

2575 -------- 

2576 >>> s = pd.Series(["1. Ant. ", "2. Bee!\\n", "3. Cat?\\t", np.nan, 10, True]) 

2577 >>> s 

2578 0 1. Ant. 

2579 1 2. Bee!\\n 

2580 2 3. Cat?\\t 

2581 3 NaN 

2582 4 10 

2583 5 True 

2584 dtype: object 

2585 

2586 >>> s.str.strip() 

2587 0 1. Ant. 

2588 1 2. Bee! 

2589 2 3. Cat? 

2590 3 NaN 

2591 4 NaN 

2592 5 NaN 

2593 dtype: object 

2594 

2595 >>> s.str.lstrip("123.") 

2596 0 Ant. 

2597 1 Bee!\\n 

2598 2 Cat?\\t 

2599 3 NaN 

2600 4 NaN 

2601 5 NaN 

2602 dtype: object 

2603 

2604 >>> s.str.rstrip(".!? \\n\\t") 

2605 0 1. Ant 

2606 1 2. Bee 

2607 2 3. Cat 

2608 3 NaN 

2609 4 NaN 

2610 5 NaN 

2611 dtype: object 

2612 

2613 >>> s.str.strip("123.!? \\n\\t") 

2614 0 Ant 

2615 1 Bee 

2616 2 Cat 

2617 3 NaN 

2618 4 NaN 

2619 5 NaN 

2620 dtype: object 

2621 """ 

2622 result = self._data.array._str_strip(to_strip) 

2623 return self._wrap_result(result) 

2624 

2625 @forbid_nonstring_types(["bytes"]) 

2626 def lstrip(self, to_strip=None): 

2627 """ 

2628 Remove leading characters. 

2629 

2630 Strip whitespaces (including newlines) or a set of specified characters 

2631 from each string in the Series/Index from left side. 

2632 Replaces any non-strings in Series with NaNs. 

2633 Equivalent to :meth:`str.lstrip`. 

2634 

2635 Parameters 

2636 ---------- 

2637 to_strip : str or None, default None 

2638 Specifying the set of characters to be removed. 

2639 All combinations of this set of characters will be stripped. 

2640 If None then whitespaces are removed. 

2641 

2642 Returns 

2643 ------- 

2644 Series or Index of object 

2645 Series or Index with the strings being stripped from the left side. 

2646 

2647 See Also 

2648 -------- 

2649 Series.str.strip : Remove leading and trailing characters in Series/Index. 

2650 Series.str.lstrip : Remove leading characters in Series/Index. 

2651 Series.str.rstrip : Remove trailing characters in Series/Index. 

2652 

2653 Examples 

2654 -------- 

2655 >>> s = pd.Series(["1. Ant. ", "2. Bee!\\n", "3. Cat?\\t", np.nan, 10, True]) 

2656 >>> s 

2657 0 1. Ant. 

2658 1 2. Bee!\\n 

2659 2 3. Cat?\\t 

2660 3 NaN 

2661 4 10 

2662 5 True 

2663 dtype: object 

2664 

2665 >>> s.str.strip() 

2666 0 1. Ant. 

2667 1 2. Bee! 

2668 2 3. Cat? 

2669 3 NaN 

2670 4 NaN 

2671 5 NaN 

2672 dtype: object 

2673 

2674 >>> s.str.lstrip("123.") 

2675 0 Ant. 

2676 1 Bee!\\n 

2677 2 Cat?\\t 

2678 3 NaN 

2679 4 NaN 

2680 5 NaN 

2681 dtype: object 

2682 

2683 >>> s.str.rstrip(".!? \\n\\t") 

2684 0 1. Ant 

2685 1 2. Bee 

2686 2 3. Cat 

2687 3 NaN 

2688 4 NaN 

2689 5 NaN 

2690 dtype: object 

2691 

2692 >>> s.str.strip("123.!? \\n\\t") 

2693 0 Ant 

2694 1 Bee 

2695 2 Cat 

2696 3 NaN 

2697 4 NaN 

2698 5 NaN 

2699 dtype: object 

2700 """ 

2701 result = self._data.array._str_lstrip(to_strip) 

2702 return self._wrap_result(result) 

2703 

2704 @forbid_nonstring_types(["bytes"]) 

2705 def rstrip(self, to_strip=None): 

2706 """ 

2707 Remove trailing characters. 

2708 

2709 Strip whitespaces (including newlines) or a set of specified characters 

2710 from each string in the Series/Index from right side. 

2711 Replaces any non-strings in Series with NaNs. 

2712 Equivalent to :meth:`str.rstrip`. 

2713 

2714 Parameters 

2715 ---------- 

2716 to_strip : str or None, default None 

2717 Specifying the set of characters to be removed. 

2718 All combinations of this set of characters will be stripped. 

2719 If None then whitespaces are removed. 

2720 

2721 Returns 

2722 ------- 

2723 Series or Index of object 

2724 Series or Index with the strings being stripped from the right side. 

2725 

2726 See Also 

2727 -------- 

2728 Series.str.strip : Remove leading and trailing characters in Series/Index. 

2729 Series.str.lstrip : Remove leading characters in Series/Index. 

2730 Series.str.rstrip : Remove trailing characters in Series/Index. 

2731 

2732 Examples 

2733 -------- 

2734 >>> s = pd.Series(["1. Ant. ", "2. Bee!\\n", "3. Cat?\\t", np.nan, 10, True]) 

2735 >>> s 

2736 0 1. Ant. 

2737 1 2. Bee!\\n 

2738 2 3. Cat?\\t 

2739 3 NaN 

2740 4 10 

2741 5 True 

2742 dtype: object 

2743 

2744 >>> s.str.strip() 

2745 0 1. Ant. 

2746 1 2. Bee! 

2747 2 3. Cat? 

2748 3 NaN 

2749 4 NaN 

2750 5 NaN 

2751 dtype: object 

2752 

2753 >>> s.str.lstrip("123.") 

2754 0 Ant. 

2755 1 Bee!\\n 

2756 2 Cat?\\t 

2757 3 NaN 

2758 4 NaN 

2759 5 NaN 

2760 dtype: object 

2761 

2762 >>> s.str.rstrip(".!? \\n\\t") 

2763 0 1. Ant 

2764 1 2. Bee 

2765 2 3. Cat 

2766 3 NaN 

2767 4 NaN 

2768 5 NaN 

2769 dtype: object 

2770 

2771 >>> s.str.strip("123.!? \\n\\t") 

2772 0 Ant 

2773 1 Bee 

2774 2 Cat 

2775 3 NaN 

2776 4 NaN 

2777 5 NaN 

2778 dtype: object 

2779 """ 

2780 result = self._data.array._str_rstrip(to_strip) 

2781 return self._wrap_result(result) 

2782 

2783 @forbid_nonstring_types(["bytes"]) 

2784 def removeprefix(self, prefix: str): 

2785 """ 

2786 Remove a prefix from an object series. 

2787 

2788 If the prefix is not present, the original string will be returned. 

2789 

2790 Parameters 

2791 ---------- 

2792 prefix : str 

2793 Remove the prefix of the string. 

2794 

2795 Returns 

2796 ------- 

2797 Series/Index: object 

2798 The Series or Index with given prefix removed. 

2799 

2800 See Also 

2801 -------- 

2802 Series.str.removesuffix : Remove a suffix from an object series. 

2803 

2804 Examples 

2805 -------- 

2806 >>> s = pd.Series(["str_foo", "str_bar", "no_prefix"]) 

2807 >>> s 

2808 0 str_foo 

2809 1 str_bar 

2810 2 no_prefix 

2811 dtype: str 

2812 >>> s.str.removeprefix("str_") 

2813 0 foo 

2814 1 bar 

2815 2 no_prefix 

2816 dtype: str 

2817 

2818 >>> s = pd.Series(["foo_str", "bar_str", "no_suffix"]) 

2819 >>> s 

2820 0 foo_str 

2821 1 bar_str 

2822 2 no_suffix 

2823 dtype: str 

2824 >>> s.str.removesuffix("_str") 

2825 0 foo 

2826 1 bar 

2827 2 no_suffix 

2828 dtype: str 

2829 """ 

2830 result = self._data.array._str_removeprefix(prefix) 

2831 return self._wrap_result(result) 

2832 

2833 @forbid_nonstring_types(["bytes"]) 

2834 def removesuffix(self, suffix: str): 

2835 """ 

2836 Remove a suffix from an object series. 

2837 

2838 If the suffix is not present, the original string will be returned. 

2839 

2840 Parameters 

2841 ---------- 

2842 suffix : str 

2843 Remove the suffix of the string. 

2844 

2845 Returns 

2846 ------- 

2847 Series/Index: object 

2848 The Series or Index with given suffix removed. 

2849 

2850 See Also 

2851 -------- 

2852 Series.str.removeprefix : Remove a prefix from an object series. 

2853 

2854 Examples 

2855 -------- 

2856 >>> s = pd.Series(["str_foo", "str_bar", "no_prefix"]) 

2857 >>> s 

2858 0 str_foo 

2859 1 str_bar 

2860 2 no_prefix 

2861 dtype: str 

2862 >>> s.str.removeprefix("str_") 

2863 0 foo 

2864 1 bar 

2865 2 no_prefix 

2866 dtype: str 

2867 

2868 >>> s = pd.Series(["foo_str", "bar_str", "no_suffix"]) 

2869 >>> s 

2870 0 foo_str 

2871 1 bar_str 

2872 2 no_suffix 

2873 dtype: str 

2874 >>> s.str.removesuffix("_str") 

2875 0 foo 

2876 1 bar 

2877 2 no_suffix 

2878 dtype: str 

2879 """ 

2880 result = self._data.array._str_removesuffix(suffix) 

2881 return self._wrap_result(result) 

2882 

2883 @forbid_nonstring_types(["bytes"]) 

2884 def wrap( 

2885 self, 

2886 width: int, 

2887 expand_tabs: bool = True, 

2888 tabsize: int = 8, 

2889 replace_whitespace: bool = True, 

2890 drop_whitespace: bool = True, 

2891 initial_indent: str = "", 

2892 subsequent_indent: str = "", 

2893 fix_sentence_endings: bool = False, 

2894 break_long_words: bool = True, 

2895 break_on_hyphens: bool = True, 

2896 max_lines: int | None = None, 

2897 placeholder: str = " [...]", 

2898 ): 

2899 r""" 

2900 Wrap strings in Series/Index at specified line width. 

2901 

2902 This method has the same keyword parameters and defaults as 

2903 :class:`textwrap.TextWrapper`. 

2904 

2905 Parameters 

2906 ---------- 

2907 width : int, optional 

2908 Maximum line width. 

2909 expand_tabs : bool, optional 

2910 If True, tab characters will be expanded to spaces (default: True). 

2911 tabsize : int, optional 

2912 If expand_tabs is true, then all tab characters in text will be 

2913 expanded to zero or more spaces, depending on the current column 

2914 and the given tab size (default: 8). 

2915 replace_whitespace : bool, optional 

2916 If True, each whitespace character (as defined by string.whitespace) 

2917 remaining after tab expansion will be replaced by a single space 

2918 (default: True). 

2919 drop_whitespace : bool, optional 

2920 If True, whitespace that, after wrapping, happens to end up at the 

2921 beginning or end of a line is dropped (default: True). 

2922 initial_indent : str, optional 

2923 String that will be prepended to the first line of wrapped output. 

2924 Counts towards the length of the first line. The empty string is 

2925 not indented (default: ''). 

2926 subsequent_indent : str, optional 

2927 String that will be prepended to all lines of wrapped output except 

2928 the first. Counts towards the length of each line except the first 

2929 (default: ''). 

2930 fix_sentence_endings : bool, optional 

2931 If true, TextWrapper attempts to detect sentence endings and ensure 

2932 that sentences are always separated by exactly two spaces. This is 

2933 generally desired for text in a monospaced font. However, the sentence 

2934 detection algorithm is imperfect: it assumes that a sentence ending 

2935 consists of a lowercase letter followed by one of '.', '!', or '?', 

2936 possibly followed by one of '"' or "'", followed by a space. One 

2937 problem with this algorithm is that it is unable to detect the 

2938 difference between “Dr.” in `[...] Dr. Frankenstein's monster [...]` 

2939 and “Spot.” in `[...] See Spot. See Spot run [...]` 

2940 Since the sentence detection algorithm relies on string.lowercase 

2941 for the definition of “lowercase letter”, and a convention of using 

2942 two spaces after a period to separate sentences on the same line, 

2943 it is specific to English-language texts (default: False). 

2944 break_long_words : bool, optional 

2945 If True, then words longer than width will be broken in order to ensure 

2946 that no lines are longer than width. If it is false, long words will 

2947 not be broken, and some lines may be longer than width (default: True). 

2948 break_on_hyphens : bool, optional 

2949 If True, wrapping will occur preferably on whitespace and right after 

2950 hyphens in compound words, as it is customary in English. If false, 

2951 only whitespaces will be considered as potentially good places for line 

2952 breaks, but you need to set break_long_words to false if you want truly 

2953 insecable words (default: True). 

2954 max_lines : int, optional 

2955 If not None, then the output will contain at most max_lines lines, with 

2956 placeholder appearing at the end of the output (default: None). 

2957 placeholder : str, optional 

2958 String that will appear at the end of the output text if it has been 

2959 truncated (default: ' [...]'). 

2960 

2961 Returns 

2962 ------- 

2963 Series or Index 

2964 A Series or Index where the strings are wrapped at the specified line width. 

2965 

2966 See Also 

2967 -------- 

2968 Series.str.strip : Remove leading and trailing characters in Series/Index. 

2969 Series.str.lstrip : Remove leading characters in Series/Index. 

2970 Series.str.rstrip : Remove trailing characters in Series/Index. 

2971 

2972 Notes 

2973 ----- 

2974 Internally, this method uses a :class:`textwrap.TextWrapper` instance with 

2975 default settings. To achieve behavior matching R's stringr library str_wrap 

2976 function, use the arguments: 

2977 

2978 - expand_tabs = False 

2979 - replace_whitespace = True 

2980 - drop_whitespace = True 

2981 - break_long_words = False 

2982 - break_on_hyphens = False 

2983 

2984 Examples 

2985 -------- 

2986 >>> s = pd.Series(["line to be wrapped", "another line to be wrapped"]) 

2987 >>> s.str.wrap(12) 

2988 0 line to be\nwrapped 

2989 1 another line\nto be\nwrapped 

2990 dtype: str 

2991 """ 

2992 result = self._data.array._str_wrap( 

2993 width=width, 

2994 expand_tabs=expand_tabs, 

2995 tabsize=tabsize, 

2996 replace_whitespace=replace_whitespace, 

2997 drop_whitespace=drop_whitespace, 

2998 initial_indent=initial_indent, 

2999 subsequent_indent=subsequent_indent, 

3000 fix_sentence_endings=fix_sentence_endings, 

3001 break_long_words=break_long_words, 

3002 break_on_hyphens=break_on_hyphens, 

3003 max_lines=max_lines, 

3004 placeholder=placeholder, 

3005 ) 

3006 return self._wrap_result(result) 

3007 

3008 @forbid_nonstring_types(["bytes"]) 

3009 def get_dummies( 

3010 self, 

3011 sep: str = "|", 

3012 dtype: NpDtype | None = None, 

3013 ): 

3014 """ 

3015 Return DataFrame of dummy/indicator variables for Series. 

3016 

3017 Each string in Series is split by sep and returned as a DataFrame 

3018 of dummy/indicator variables. 

3019 

3020 Parameters 

3021 ---------- 

3022 sep : str, default "|" 

3023 String to split on. 

3024 dtype : dtype, default np.int64 

3025 Data type for new columns. Only a single dtype is allowed. 

3026 

3027 Returns 

3028 ------- 

3029 DataFrame 

3030 Dummy variables corresponding to values of the Series. 

3031 

3032 See Also 

3033 -------- 

3034 get_dummies : Convert categorical variable into dummy/indicator 

3035 variables. 

3036 

3037 Examples 

3038 -------- 

3039 >>> pd.Series(["a|b", "a", "a|c"]).str.get_dummies() 

3040 a b c 

3041 0 1 1 0 

3042 1 1 0 0 

3043 2 1 0 1 

3044 

3045 >>> pd.Series(["a|b", np.nan, "a|c"]).str.get_dummies() 

3046 a b c 

3047 0 1 1 0 

3048 1 0 0 0 

3049 2 1 0 1 

3050 

3051 >>> pd.Series(["a|b", np.nan, "a|c"]).str.get_dummies(dtype=bool) 

3052 a b c 

3053 0 True True False 

3054 1 False False False 

3055 2 True False True 

3056 """ 

3057 from pandas.core.frame import DataFrame 

3058 

3059 if dtype is not None and not (is_numeric_dtype(dtype) or is_bool_dtype(dtype)): 

3060 raise ValueError("Only numeric or boolean dtypes are supported for 'dtype'") 

3061 # we need to cast to Series of strings as only that has all 

3062 # methods available for making the dummies... 

3063 result, name = self._data.array._str_get_dummies(sep, dtype) 

3064 if is_extension_array_dtype(dtype): 

3065 return self._wrap_result( 

3066 DataFrame(result, columns=name, dtype=dtype), 

3067 name=name, 

3068 returns_string=False, 

3069 ) 

3070 return self._wrap_result( 

3071 result, 

3072 name=name, 

3073 expand=True, 

3074 returns_string=False, 

3075 ) 

3076 

3077 @forbid_nonstring_types(["bytes"]) 

3078 def translate(self, table): 

3079 """ 

3080 Map all characters in the string through the given mapping table. 

3081 

3082 This method is equivalent to the standard :meth:`str.translate` 

3083 method for strings. It maps each character in the string to a new 

3084 character according to the translation table provided. Unmapped 

3085 characters are left unchanged, while characters mapped to None 

3086 are removed. 

3087 

3088 Parameters 

3089 ---------- 

3090 table : dict 

3091 Table is a mapping of Unicode ordinals to Unicode ordinals, strings, or 

3092 None. Unmapped characters are left untouched. 

3093 Characters mapped to None are deleted. :meth:`str.maketrans` is a 

3094 helper function for making translation tables. 

3095 

3096 Returns 

3097 ------- 

3098 Series or Index 

3099 A new Series or Index with translated strings. 

3100 

3101 See Also 

3102 -------- 

3103 Series.str.replace : Replace occurrences of pattern/regex in the 

3104 Series with some other string. 

3105 Index.str.replace : Replace occurrences of pattern/regex in the 

3106 Index with some other string. 

3107 

3108 Examples 

3109 -------- 

3110 >>> ser = pd.Series(["El niño", "Françoise"]) 

3111 >>> mytable = str.maketrans({"ñ": "n", "ç": "c"}) 

3112 >>> ser.str.translate(mytable) 

3113 0 El nino 

3114 1 Francoise 

3115 dtype: str 

3116 """ 

3117 result = self._data.array._str_translate(table) 

3118 dtype = object if self._data.dtype == "object" else None 

3119 return self._wrap_result(result, dtype=dtype) 

3120 

3121 @forbid_nonstring_types(["bytes"]) 

3122 def count(self, pat, flags: int = 0): 

3123 r""" 

3124 Count occurrences of pattern in each string of the Series/Index. 

3125 

3126 This function is used to count the number of times a particular regex 

3127 pattern is repeated in each of the string elements of the 

3128 :class:`~pandas.Series`. 

3129 

3130 Parameters 

3131 ---------- 

3132 pat : str 

3133 Valid regular expression. 

3134 flags : int, default 0, meaning no flags 

3135 Flags for the `re` module. For a complete list, `see here 

3136 <https://docs.python.org/3/howto/regex.html#compilation-flags>`_. 

3137 

3138 Returns 

3139 ------- 

3140 Series or Index 

3141 Same type as the calling object containing the integer counts. 

3142 

3143 See Also 

3144 -------- 

3145 re : Standard library module for regular expressions. 

3146 str.count : Standard library version, without regular expression support. 

3147 

3148 Notes 

3149 ----- 

3150 Some characters need to be escaped when passing in `pat`. 

3151 eg. ``'$'`` has a special meaning in regex and must be escaped when 

3152 finding this literal character. 

3153 

3154 Examples 

3155 -------- 

3156 >>> s = pd.Series(["A", "B", "Aaba", "Baca", np.nan, "CABA", "cat"]) 

3157 >>> s.str.count("a") 

3158 0 0.0 

3159 1 0.0 

3160 2 2.0 

3161 3 2.0 

3162 4 NaN 

3163 5 0.0 

3164 6 1.0 

3165 dtype: float64 

3166 

3167 Escape ``'$'`` to find the literal dollar sign. 

3168 

3169 >>> s = pd.Series(["$", "B", "Aab$", "$$ca", "C$B$", "cat"]) 

3170 >>> s.str.count("\\$") 

3171 0 1 

3172 1 0 

3173 2 1 

3174 3 2 

3175 4 2 

3176 5 0 

3177 dtype: int64 

3178 

3179 This is also available on Index 

3180 

3181 >>> pd.Index(["A", "A", "Aaba", "cat"]).str.count("a") 

3182 Index([0, 0, 2, 1], dtype='int64') 

3183 """ 

3184 result = self._data.array._str_count(pat, flags) 

3185 return self._wrap_result(result, returns_string=False) 

3186 

3187 @forbid_nonstring_types(["bytes"]) 

3188 def startswith( 

3189 self, pat: str | tuple[str, ...], na: Scalar | lib.NoDefault = lib.no_default 

3190 ) -> Series | Index: 

3191 """ 

3192 Test if the start of each string element matches a pattern. 

3193 

3194 Equivalent to :meth:`str.startswith`. 

3195 

3196 Parameters 

3197 ---------- 

3198 pat : str or tuple[str, ...] 

3199 Character sequence or tuple of strings. Regular expressions are not 

3200 accepted. 

3201 na : scalar, optional 

3202 Object shown if element tested is not a string. The default depends 

3203 on dtype of the array. For the ``"str"`` dtype, ``False`` is used. 

3204 For object dtype, ``numpy.nan`` is used. For the nullable 

3205 ``StringDtype``, ``pandas.NA`` is used. 

3206 

3207 Returns 

3208 ------- 

3209 Series or Index of bool 

3210 A Series of booleans indicating whether the given pattern matches 

3211 the start of each string element. 

3212 

3213 See Also 

3214 -------- 

3215 str.startswith : Python standard library string method. 

3216 Series.str.endswith : Same as startswith, but tests the end of string. 

3217 Series.str.contains : Tests if string element contains a pattern. 

3218 

3219 Examples 

3220 -------- 

3221 >>> s = pd.Series(["bat", "Bear", "cat", np.nan]) 

3222 >>> s 

3223 0 bat 

3224 1 Bear 

3225 2 cat 

3226 3 NaN 

3227 dtype: str 

3228 

3229 >>> s.str.startswith("b") 

3230 0 True 

3231 1 False 

3232 2 False 

3233 3 False 

3234 dtype: bool 

3235 

3236 >>> s.str.startswith(("b", "B")) 

3237 0 True 

3238 1 True 

3239 2 False 

3240 3 False 

3241 dtype: bool 

3242 """ 

3243 if not isinstance(pat, (str, tuple)): 

3244 msg = f"expected a string or tuple, not {type(pat).__name__}" 

3245 raise TypeError(msg) 

3246 result = self._data.array._str_startswith(pat, na=na) 

3247 return self._wrap_result(result, returns_string=False) 

3248 

3249 @forbid_nonstring_types(["bytes"]) 

3250 def endswith( 

3251 self, pat: str | tuple[str, ...], na: Scalar | lib.NoDefault = lib.no_default 

3252 ) -> Series | Index: 

3253 """ 

3254 Test if the end of each string element matches a pattern. 

3255 

3256 Equivalent to :meth:`str.endswith`. 

3257 

3258 Parameters 

3259 ---------- 

3260 pat : str or tuple[str, ...] 

3261 Character sequence or tuple of strings. Regular expressions are not 

3262 accepted. 

3263 na : scalar, optional 

3264 Object shown if element tested is not a string. The default depends 

3265 on dtype of the array. For the ``"str"`` dtype, ``False`` is used. 

3266 For object dtype, ``numpy.nan`` is used. For the nullable 

3267 ``StringDtype``, ``pandas.NA`` is used. 

3268 

3269 Returns 

3270 ------- 

3271 Series or Index of bool 

3272 A Series of booleans indicating whether the given pattern matches 

3273 the end of each string element. 

3274 

3275 See Also 

3276 -------- 

3277 str.endswith : Python standard library string method. 

3278 Series.str.startswith : Same as endswith, but tests the start of string. 

3279 Series.str.contains : Tests if string element contains a pattern. 

3280 

3281 Examples 

3282 -------- 

3283 >>> s = pd.Series(["bat", "bear", "caT", np.nan]) 

3284 >>> s 

3285 0 bat 

3286 1 bear 

3287 2 caT 

3288 3 NaN 

3289 dtype: str 

3290 

3291 >>> s.str.endswith("t") 

3292 0 True 

3293 1 False 

3294 2 False 

3295 3 False 

3296 dtype: bool 

3297 

3298 >>> s.str.endswith(("t", "T")) 

3299 0 True 

3300 1 False 

3301 2 True 

3302 3 False 

3303 dtype: bool 

3304 """ 

3305 if not isinstance(pat, (str, tuple)): 

3306 msg = f"expected a string or tuple, not {type(pat).__name__}" 

3307 raise TypeError(msg) 

3308 result = self._data.array._str_endswith(pat, na=na) 

3309 return self._wrap_result(result, returns_string=False) 

3310 

3311 @forbid_nonstring_types(["bytes"]) 

3312 def findall(self, pat, flags: int = 0): 

3313 """ 

3314 Find all occurrences of pattern or regular expression in the Series/Index. 

3315 

3316 Equivalent to applying :func:`re.findall` to all the elements in the 

3317 Series/Index. 

3318 

3319 Parameters 

3320 ---------- 

3321 pat : str 

3322 Pattern or regular expression. 

3323 flags : int, default 0 

3324 Flags from ``re`` module, e.g. `re.IGNORECASE` (default is 0, which 

3325 means no flags). 

3326 

3327 Returns 

3328 ------- 

3329 Series/Index of lists of strings 

3330 All non-overlapping matches of pattern or regular expression in each 

3331 string of this Series/Index. 

3332 

3333 See Also 

3334 -------- 

3335 count : Count occurrences of pattern or regular expression in each string 

3336 of the Series/Index. 

3337 extractall : For each string in the Series, extract groups from all matches 

3338 of regular expression and return a DataFrame with one row for each 

3339 match and one column for each group. 

3340 re.findall : The equivalent ``re`` function to all non-overlapping matches 

3341 of pattern or regular expression in string, as a list of strings. 

3342 

3343 Examples 

3344 -------- 

3345 >>> s = pd.Series(["Lion", "Monkey", "Rabbit"]) 

3346 

3347 The search for the pattern 'Monkey' returns one match: 

3348 

3349 >>> s.str.findall("Monkey") 

3350 0 [] 

3351 1 [Monkey] 

3352 2 [] 

3353 dtype: object 

3354 

3355 On the other hand, the search for the pattern 'MONKEY' doesn't return any 

3356 match: 

3357 

3358 >>> s.str.findall("MONKEY") 

3359 0 [] 

3360 1 [] 

3361 2 [] 

3362 dtype: object 

3363 

3364 Flags can be added to the pattern or regular expression. For instance, 

3365 to find the pattern 'MONKEY' ignoring the case: 

3366 

3367 >>> import re 

3368 >>> s.str.findall("MONKEY", flags=re.IGNORECASE) 

3369 0 [] 

3370 1 [Monkey] 

3371 2 [] 

3372 dtype: object 

3373 

3374 When the pattern matches more than one string in the Series, all matches 

3375 are returned: 

3376 

3377 >>> s.str.findall("on") 

3378 0 [on] 

3379 1 [on] 

3380 2 [] 

3381 dtype: object 

3382 

3383 Regular expressions are supported too. For instance, the search for all the 

3384 strings ending with the word 'on' is shown next: 

3385 

3386 >>> s.str.findall("on$") 

3387 0 [on] 

3388 1 [] 

3389 2 [] 

3390 dtype: object 

3391 

3392 If the pattern is found more than once in the same string, then a list of 

3393 multiple strings is returned: 

3394 

3395 >>> s.str.findall("b") 

3396 0 [] 

3397 1 [] 

3398 2 [b, b] 

3399 dtype: object 

3400 """ 

3401 result = self._data.array._str_findall(pat, flags) 

3402 return self._wrap_result(result, returns_string=False) 

3403 

3404 @forbid_nonstring_types(["bytes"]) 

3405 def extract( 

3406 self, pat: str, flags: int = 0, expand: bool = True 

3407 ) -> DataFrame | Series | Index: 

3408 r""" 

3409 Extract capture groups in the regex `pat` as columns in a DataFrame. 

3410 

3411 For each subject string in the Series, extract groups from the 

3412 first match of regular expression `pat`. 

3413 

3414 Parameters 

3415 ---------- 

3416 pat : str 

3417 Regular expression pattern with capturing groups. 

3418 flags : int, default 0 (no flags) 

3419 Flags from the ``re`` module, e.g. ``re.IGNORECASE``, that 

3420 modify regular expression matching for things like case, 

3421 spaces, etc. For more details, see :mod:`re`. 

3422 expand : bool, default True 

3423 If True, return DataFrame with one column per capture group. 

3424 If False, return a Series/Index if there is one capture group 

3425 or DataFrame if there are multiple capture groups. 

3426 

3427 Returns 

3428 ------- 

3429 DataFrame or Series or Index 

3430 A DataFrame with one row for each subject string, and one 

3431 column for each group. Any capture group names in regular 

3432 expression pat will be used for column names; otherwise 

3433 capture group numbers will be used. The dtype of each result 

3434 column is always object, even when no match is found. If 

3435 ``expand=False`` and pat has only one capture group, then 

3436 return a Series (if subject is a Series) or Index (if subject 

3437 is an Index). 

3438 

3439 See Also 

3440 -------- 

3441 extractall : Returns all matches (not just the first match). 

3442 

3443 Examples 

3444 -------- 

3445 A pattern with two groups will return a DataFrame with two columns. 

3446 Non-matches will be NaN. 

3447 

3448 >>> s = pd.Series(["a1", "b2", "c3"]) 

3449 >>> s.str.extract(r"([ab])(\d)") 

3450 0 1 

3451 0 a 1 

3452 1 b 2 

3453 2 NaN NaN 

3454 

3455 A pattern may contain optional groups. 

3456 

3457 >>> s.str.extract(r"([ab])?(\d)") 

3458 0 1 

3459 0 a 1 

3460 1 b 2 

3461 2 NaN 3 

3462 

3463 Named groups will become column names in the result. 

3464 

3465 >>> s.str.extract(r"(?P<letter>[ab])(?P<digit>\d)") 

3466 letter digit 

3467 0 a 1 

3468 1 b 2 

3469 2 NaN NaN 

3470 

3471 A pattern with one group will return a DataFrame with one column 

3472 if expand=True. 

3473 

3474 >>> s.str.extract(r"[ab](\d)", expand=True) 

3475 0 

3476 0 1 

3477 1 2 

3478 2 NaN 

3479 

3480 A pattern with one group will return a Series if expand=False. 

3481 

3482 >>> s.str.extract(r"[ab](\d)", expand=False) 

3483 0 1 

3484 1 2 

3485 2 NaN 

3486 dtype: str 

3487 """ 

3488 from pandas import DataFrame 

3489 

3490 if not isinstance(expand, bool): 

3491 raise ValueError("expand must be True or False") 

3492 

3493 regex = re.compile(pat, flags=flags) 

3494 if regex.groups == 0: 

3495 raise ValueError("pattern contains no capture groups") 

3496 

3497 if not expand and regex.groups > 1 and isinstance(self._data, ABCIndex): 

3498 raise ValueError("only one regex group is supported with Index") 

3499 

3500 obj = self._data 

3501 result_dtype = _result_dtype(obj) 

3502 

3503 returns_df = regex.groups > 1 or expand 

3504 

3505 if returns_df: 

3506 name = None 

3507 columns = get_group_names(regex) 

3508 

3509 if obj.array.size == 0: 

3510 result = DataFrame(columns=columns, dtype=result_dtype) 

3511 

3512 else: 

3513 result_list = self._data.array._str_extract( 

3514 pat, flags=flags, expand=returns_df 

3515 ) 

3516 

3517 result_index: Index | None 

3518 if isinstance(obj, ABCSeries): 

3519 result_index = obj.index 

3520 else: 

3521 result_index = None 

3522 

3523 result = DataFrame( 

3524 result_list, columns=columns, index=result_index, dtype=result_dtype 

3525 ) 

3526 

3527 else: 

3528 name = _get_single_group_name(regex) 

3529 result = self._data.array._str_extract(pat, flags=flags, expand=returns_df) 

3530 return self._wrap_result(result, name=name, dtype=result_dtype) 

3531 

3532 @forbid_nonstring_types(["bytes"]) 

3533 def extractall(self, pat, flags: int = 0) -> DataFrame: 

3534 r""" 

3535 Extract capture groups in the regex `pat` as columns in DataFrame. 

3536 

3537 For each subject string in the Series, extract groups from all 

3538 matches of regular expression pat. When each subject string in the 

3539 Series has exactly one match, extractall(pat).xs(0, level='match') 

3540 is the same as extract(pat). 

3541 

3542 Parameters 

3543 ---------- 

3544 pat : str 

3545 Regular expression pattern with capturing groups. 

3546 flags : int, default 0 (no flags) 

3547 A ``re`` module flag, for example ``re.IGNORECASE``. These allow 

3548 to modify regular expression matching for things like case, spaces, 

3549 etc. Multiple flags can be combined with the bitwise OR operator, 

3550 for example ``re.IGNORECASE | re.MULTILINE``. 

3551 

3552 Returns 

3553 ------- 

3554 DataFrame 

3555 A ``DataFrame`` with one row for each match, and one column for each 

3556 group. Its rows have a ``MultiIndex`` with first levels that come from 

3557 the subject ``Series``. The last level is named 'match' and indexes the 

3558 matches in each item of the ``Series``. Any capture group names in 

3559 regular expression pat will be used for column names; otherwise capture 

3560 group numbers will be used. 

3561 

3562 See Also 

3563 -------- 

3564 extract : Returns first match only (not all matches). 

3565 

3566 Examples 

3567 -------- 

3568 A pattern with one group will return a DataFrame with one column. 

3569 Indices with no matches will not appear in the result. 

3570 

3571 >>> s = pd.Series(["a1a2", "b1", "c1"], index=["A", "B", "C"]) 

3572 >>> s.str.extractall(r"[ab](\d)") 

3573 0 

3574 match 

3575 A 0 1 

3576 1 2 

3577 B 0 1 

3578 

3579 Capture group names are used for column names of the result. 

3580 

3581 >>> s.str.extractall(r"[ab](?P<digit>\d)") 

3582 digit 

3583 match 

3584 A 0 1 

3585 1 2 

3586 B 0 1 

3587 

3588 A pattern with two groups will return a DataFrame with two columns. 

3589 

3590 >>> s.str.extractall(r"(?P<letter>[ab])(?P<digit>\d)") 

3591 letter digit 

3592 match 

3593 A 0 a 1 

3594 1 a 2 

3595 B 0 b 1 

3596 

3597 Optional groups that do not match are NaN in the result. 

3598 

3599 >>> s.str.extractall(r"(?P<letter>[ab])?(?P<digit>\d)") 

3600 letter digit 

3601 match 

3602 A 0 a 1 

3603 1 a 2 

3604 B 0 b 1 

3605 C 0 NaN 1 

3606 """ 

3607 # TODO: dispatch 

3608 return str_extractall(self._orig, pat, flags) 

3609 

3610 @forbid_nonstring_types(["bytes"]) 

3611 def find(self, sub, start: int = 0, end=None): 

3612 """ 

3613 Return lowest indexes in each strings in the Series/Index. 

3614 

3615 Each of returned indexes corresponds to the position where the 

3616 substring is fully contained between [start:end]. Return -1 on 

3617 failure. Equivalent to standard :meth:`str.find`. 

3618 

3619 Parameters 

3620 ---------- 

3621 sub : str 

3622 Substring being searched. 

3623 start : int 

3624 Left edge index. 

3625 end : int 

3626 Right edge index. 

3627 

3628 Returns 

3629 ------- 

3630 Series or Index of int. 

3631 A Series (if the input is a Series) or an Index (if the input is an 

3632 Index) of the lowest indexes corresponding to the positions where the 

3633 substring is found in each string of the input. 

3634 

3635 See Also 

3636 -------- 

3637 rfind : Return highest indexes in each strings. 

3638 

3639 Examples 

3640 -------- 

3641 For Series.str.find: 

3642 

3643 >>> ser = pd.Series(["_cow_", "duck_", "do_v_e"]) 

3644 >>> ser.str.find("_") 

3645 0 0 

3646 1 4 

3647 2 2 

3648 dtype: int64 

3649 

3650 For Series.str.rfind: 

3651 

3652 >>> ser = pd.Series(["_cow_", "duck_", "do_v_e"]) 

3653 >>> ser.str.rfind("_") 

3654 0 4 

3655 1 4 

3656 2 4 

3657 dtype: int64 

3658 """ 

3659 if not isinstance(sub, str): 

3660 msg = f"expected a string object, not {type(sub).__name__}" 

3661 raise TypeError(msg) 

3662 

3663 result = self._data.array._str_find(sub, start, end) 

3664 return self._wrap_result(result, returns_string=False) 

3665 

3666 @forbid_nonstring_types(["bytes"]) 

3667 def rfind(self, sub, start: int = 0, end=None): 

3668 """ 

3669 Return highest indexes in each strings in the Series/Index. 

3670 

3671 Each of returned indexes corresponds to the position where the 

3672 substring is fully contained between [start:end]. Return -1 on 

3673 failure. Equivalent to standard :meth:`str.rfind`. 

3674 

3675 Parameters 

3676 ---------- 

3677 sub : str 

3678 Substring being searched. 

3679 start : int 

3680 Left edge index. 

3681 end : int 

3682 Right edge index. 

3683 

3684 Returns 

3685 ------- 

3686 Series or Index of int. 

3687 A Series (if the input is a Series) or an Index (if the input is an 

3688 Index) of the highest indexes corresponding to the positions where the 

3689 substring is found in each string of the input. 

3690 

3691 See Also 

3692 -------- 

3693 find : Return lowest indexes in each strings. 

3694 

3695 Examples 

3696 -------- 

3697 For Series.str.find: 

3698 

3699 >>> ser = pd.Series(["_cow_", "duck_", "do_v_e"]) 

3700 >>> ser.str.find("_") 

3701 0 0 

3702 1 4 

3703 2 2 

3704 dtype: int64 

3705 

3706 For Series.str.rfind: 

3707 

3708 >>> ser = pd.Series(["_cow_", "duck_", "do_v_e"]) 

3709 >>> ser.str.rfind("_") 

3710 0 4 

3711 1 4 

3712 2 4 

3713 dtype: int64 

3714 """ 

3715 if not isinstance(sub, str): 

3716 msg = f"expected a string object, not {type(sub).__name__}" 

3717 raise TypeError(msg) 

3718 

3719 result = self._data.array._str_rfind(sub, start=start, end=end) 

3720 return self._wrap_result(result, returns_string=False) 

3721 

3722 @forbid_nonstring_types(["bytes"]) 

3723 def normalize(self, form): 

3724 """ 

3725 Return the Unicode normal form for the strings in the Series/Index. 

3726 

3727 For more information on the forms, see the 

3728 :func:`unicodedata.normalize`. 

3729 

3730 Parameters 

3731 ---------- 

3732 form : {'NFC', 'NFKC', 'NFD', 'NFKD'} 

3733 Unicode form. 

3734 

3735 Returns 

3736 ------- 

3737 Series/Index of objects 

3738 A Series or Index of strings in the same Unicode form specified by `form`. 

3739 The returned object retains the same type as the input (Series or Index), 

3740 and contains the normalized strings. 

3741 

3742 See Also 

3743 -------- 

3744 Series.str.upper : Convert all characters in each string to uppercase. 

3745 Series.str.lower : Convert all characters in each string to lowercase. 

3746 Series.str.title : Convert each string to title case (capitalizing the 

3747 first letter of each word). 

3748 Series.str.strip : Remove leading and trailing whitespace from each string. 

3749 Series.str.replace : Replace occurrences of a substring with another substring 

3750 in each string. 

3751 

3752 Examples 

3753 -------- 

3754 >>> ser = pd.Series(["ñ"]) 

3755 >>> ser.str.normalize("NFC") == ser.str.normalize("NFD") 

3756 0 False 

3757 dtype: bool 

3758 """ 

3759 result = self._data.array._str_normalize(form) 

3760 return self._wrap_result(result) 

3761 

3762 @forbid_nonstring_types(["bytes"]) 

3763 def index(self, sub, start: int = 0, end=None): 

3764 """ 

3765 Return lowest indexes in each string in Series/Index. 

3766 

3767 Each of the returned indexes corresponds to the position where the 

3768 substring is fully contained between [start:end]. This is the same 

3769 as ``str.find`` except instead of returning -1, it raises a 

3770 ValueError when the substring is not found. Equivalent to standard 

3771 ``str.index``. 

3772 

3773 Parameters 

3774 ---------- 

3775 sub : str 

3776 Substring being searched. 

3777 start : int 

3778 Left edge index. 

3779 end : int 

3780 Right edge index. 

3781 

3782 Returns 

3783 ------- 

3784 Series or Index of object 

3785 Returns a Series or an Index of the lowest indexes 

3786 in each string of the input. 

3787 

3788 See Also 

3789 -------- 

3790 rindex : Return highest indexes in each strings. 

3791 

3792 Examples 

3793 -------- 

3794 For Series.str.index: 

3795 

3796 >>> ser = pd.Series(["horse", "eagle", "donkey"]) 

3797 >>> ser.str.index("e") 

3798 0 4 

3799 1 0 

3800 2 4 

3801 dtype: int64 

3802 

3803 For Series.str.rindex: 

3804 

3805 >>> ser = pd.Series(["Deer", "eagle", "Sheep"]) 

3806 >>> ser.str.rindex("e") 

3807 0 2 

3808 1 4 

3809 2 3 

3810 dtype: int64 

3811 """ 

3812 if not isinstance(sub, str): 

3813 msg = f"expected a string object, not {type(sub).__name__}" 

3814 raise TypeError(msg) 

3815 

3816 result = self._data.array._str_index(sub, start=start, end=end) 

3817 return self._wrap_result(result, returns_string=False) 

3818 

3819 @forbid_nonstring_types(["bytes"]) 

3820 def rindex(self, sub, start: int = 0, end=None): 

3821 """ 

3822 Return highest indexes in each string in Series/Index. 

3823 

3824 Each of the returned indexes corresponds to the position where the 

3825 substring is fully contained between [start:end]. This is the same 

3826 as ``str.rfind`` except instead of returning -1, it raises a 

3827 ValueError when the substring is not found. Equivalent to standard 

3828 ``str.rindex``. 

3829 

3830 Parameters 

3831 ---------- 

3832 sub : str 

3833 Substring being searched. 

3834 start : int 

3835 Left edge index. 

3836 end : int 

3837 Right edge index. 

3838 

3839 Returns 

3840 ------- 

3841 Series or Index of object 

3842 Returns a Series or an Index of the highest indexes 

3843 in each string of the input. 

3844 

3845 See Also 

3846 -------- 

3847 index : Return lowest indexes in each strings. 

3848 

3849 Examples 

3850 -------- 

3851 For Series.str.index: 

3852 

3853 >>> ser = pd.Series(["horse", "eagle", "donkey"]) 

3854 >>> ser.str.index("e") 

3855 0 4 

3856 1 0 

3857 2 4 

3858 dtype: int64 

3859 

3860 For Series.str.rindex: 

3861 

3862 >>> ser = pd.Series(["Deer", "eagle", "Sheep"]) 

3863 >>> ser.str.rindex("e") 

3864 0 2 

3865 1 4 

3866 2 3 

3867 dtype: int64 

3868 """ 

3869 if not isinstance(sub, str): 

3870 msg = f"expected a string object, not {type(sub).__name__}" 

3871 raise TypeError(msg) 

3872 

3873 result = self._data.array._str_rindex(sub, start=start, end=end) 

3874 return self._wrap_result(result, returns_string=False) 

3875 

3876 def len(self): 

3877 """ 

3878 Compute the length of each element in the Series/Index. 

3879 

3880 The element may be a sequence (such as a string, tuple or list) or a collection 

3881 (such as a dictionary). 

3882 

3883 Returns 

3884 ------- 

3885 Series or Index of int 

3886 A Series or Index of integer values indicating the length of each 

3887 element in the Series or Index. 

3888 

3889 See Also 

3890 -------- 

3891 str.len : Python built-in function returning the length of an object. 

3892 Series.size : Returns the length of the Series. 

3893 

3894 Examples 

3895 -------- 

3896 Returns the length (number of characters) in a string. Returns the 

3897 number of entries for dictionaries, lists or tuples. 

3898 

3899 >>> s = pd.Series( 

3900 ... ["dog", "", 5, {"foo": "bar"}, [2, 3, 5, 7], ("one", "two", "three")] 

3901 ... ) 

3902 >>> s 

3903 0 dog 

3904 1 

3905 2 5 

3906 3 {'foo': 'bar'} 

3907 4 [2, 3, 5, 7] 

3908 5 (one, two, three) 

3909 dtype: object 

3910 >>> s.str.len() 

3911 0 3.0 

3912 1 0.0 

3913 2 NaN 

3914 3 1.0 

3915 4 4.0 

3916 5 3.0 

3917 dtype: float64 

3918 """ 

3919 result = self._data.array._str_len() 

3920 return self._wrap_result(result, returns_string=False) 

3921 

3922 @forbid_nonstring_types(["bytes"]) 

3923 def lower(self): 

3924 """ 

3925 Convert strings in the Series/Index to lowercase. 

3926 

3927 Equivalent to :meth:`str.lower`. 

3928 

3929 Returns 

3930 ------- 

3931 Series or Index of objects 

3932 A Series or Index where the strings are modified by :meth:`str.lower`. 

3933 

3934 See Also 

3935 -------- 

3936 Series.str.lower : Converts all characters to lowercase. 

3937 Series.str.upper : Converts all characters to uppercase. 

3938 Series.str.title : Converts first character of each word to uppercase and 

3939 remaining to lowercase. 

3940 Series.str.capitalize : Converts first character to uppercase and 

3941 remaining to lowercase. 

3942 Series.str.swapcase : Converts uppercase to lowercase and lowercase to 

3943 uppercase. 

3944 Series.str.casefold: Removes all case distinctions in the string. 

3945 

3946 Examples 

3947 -------- 

3948 >>> s = pd.Series(["lower", "CAPITALS", "this is a sentence", "SwApCaSe"]) 

3949 >>> s 

3950 0 lower 

3951 1 CAPITALS 

3952 2 this is a sentence 

3953 3 SwApCaSe 

3954 dtype: str 

3955 

3956 >>> s.str.lower() 

3957 0 lower 

3958 1 capitals 

3959 2 this is a sentence 

3960 3 swapcase 

3961 dtype: str 

3962 

3963 >>> s.str.upper() 

3964 0 LOWER 

3965 1 CAPITALS 

3966 2 THIS IS A SENTENCE 

3967 3 SWAPCASE 

3968 dtype: str 

3969 

3970 >>> s.str.title() 

3971 0 Lower 

3972 1 Capitals 

3973 2 This Is A Sentence 

3974 3 Swapcase 

3975 dtype: str 

3976 

3977 >>> s.str.capitalize() 

3978 0 Lower 

3979 1 Capitals 

3980 2 This is a sentence 

3981 3 Swapcase 

3982 dtype: str 

3983 

3984 >>> s.str.swapcase() 

3985 0 LOWER 

3986 1 capitals 

3987 2 THIS IS A SENTENCE 

3988 3 sWaPcAsE 

3989 dtype: str 

3990 """ 

3991 result = self._data.array._str_lower() 

3992 return self._wrap_result(result) 

3993 

3994 @forbid_nonstring_types(["bytes"]) 

3995 def upper(self): 

3996 """ 

3997 Convert strings in the Series/Index to uppercase. 

3998 

3999 Equivalent to :meth:`str.upper`. 

4000 

4001 Returns 

4002 ------- 

4003 Series or Index of objects 

4004 A Series or Index where the strings are modified by :meth:`str.upper`. 

4005 

4006 See Also 

4007 -------- 

4008 Series.str.lower : Converts all characters to lowercase. 

4009 Series.str.upper : Converts all characters to uppercase. 

4010 Series.str.title : Converts first character of each word to uppercase and 

4011 remaining to lowercase. 

4012 Series.str.capitalize : Converts first character to uppercase and 

4013 remaining to lowercase. 

4014 Series.str.swapcase : Converts uppercase to lowercase and lowercase to 

4015 uppercase. 

4016 Series.str.casefold: Removes all case distinctions in the string. 

4017 

4018 Examples 

4019 -------- 

4020 >>> s = pd.Series(["lower", "CAPITALS", "this is a sentence", "SwApCaSe"]) 

4021 >>> s 

4022 0 lower 

4023 1 CAPITALS 

4024 2 this is a sentence 

4025 3 SwApCaSe 

4026 dtype: str 

4027 

4028 >>> s.str.lower() 

4029 0 lower 

4030 1 capitals 

4031 2 this is a sentence 

4032 3 swapcase 

4033 dtype: str 

4034 

4035 >>> s.str.upper() 

4036 0 LOWER 

4037 1 CAPITALS 

4038 2 THIS IS A SENTENCE 

4039 3 SWAPCASE 

4040 dtype: str 

4041 

4042 >>> s.str.title() 

4043 0 Lower 

4044 1 Capitals 

4045 2 This Is A Sentence 

4046 3 Swapcase 

4047 dtype: str 

4048 

4049 >>> s.str.capitalize() 

4050 0 Lower 

4051 1 Capitals 

4052 2 This is a sentence 

4053 3 Swapcase 

4054 dtype: str 

4055 

4056 >>> s.str.swapcase() 

4057 0 LOWER 

4058 1 capitals 

4059 2 THIS IS A SENTENCE 

4060 3 sWaPcAsE 

4061 dtype: str 

4062 """ 

4063 result = self._data.array._str_upper() 

4064 return self._wrap_result(result) 

4065 

4066 @forbid_nonstring_types(["bytes"]) 

4067 def title(self): 

4068 """ 

4069 Convert strings in the Series/Index to titlecase. 

4070 

4071 Equivalent to :meth:`str.title`. 

4072 

4073 Returns 

4074 ------- 

4075 Series or Index of objects 

4076 A Series or Index where the strings are modified by :meth:`str.title`. 

4077 

4078 See Also 

4079 -------- 

4080 Series.str.lower : Converts all characters to lowercase. 

4081 Series.str.upper : Converts all characters to uppercase. 

4082 Series.str.title : Converts first character of each word to uppercase and 

4083 remaining to lowercase. 

4084 Series.str.capitalize : Converts first character to uppercase and 

4085 remaining to lowercase. 

4086 Series.str.swapcase : Converts uppercase to lowercase and lowercase to 

4087 uppercase. 

4088 Series.str.casefold: Removes all case distinctions in the string. 

4089 

4090 Examples 

4091 -------- 

4092 >>> s = pd.Series(["lower", "CAPITALS", "this is a sentence", "SwApCaSe"]) 

4093 >>> s 

4094 0 lower 

4095 1 CAPITALS 

4096 2 this is a sentence 

4097 3 SwApCaSe 

4098 dtype: str 

4099 

4100 >>> s.str.lower() 

4101 0 lower 

4102 1 capitals 

4103 2 this is a sentence 

4104 3 swapcase 

4105 dtype: str 

4106 

4107 >>> s.str.upper() 

4108 0 LOWER 

4109 1 CAPITALS 

4110 2 THIS IS A SENTENCE 

4111 3 SWAPCASE 

4112 dtype: str 

4113 

4114 >>> s.str.title() 

4115 0 Lower 

4116 1 Capitals 

4117 2 This Is A Sentence 

4118 3 Swapcase 

4119 dtype: str 

4120 

4121 >>> s.str.capitalize() 

4122 0 Lower 

4123 1 Capitals 

4124 2 This is a sentence 

4125 3 Swapcase 

4126 dtype: str 

4127 

4128 >>> s.str.swapcase() 

4129 0 LOWER 

4130 1 capitals 

4131 2 THIS IS A SENTENCE 

4132 3 sWaPcAsE 

4133 dtype: str 

4134 """ 

4135 result = self._data.array._str_title() 

4136 return self._wrap_result(result) 

4137 

4138 @forbid_nonstring_types(["bytes"]) 

4139 def capitalize(self): 

4140 """ 

4141 Convert strings in the Series/Index to be capitalized. 

4142 

4143 Equivalent to :meth:`str.capitalize`. 

4144 

4145 Returns 

4146 ------- 

4147 Series or Index of objects 

4148 A Series or Index where the strings are modified by :meth:`str.capitalize`. 

4149 

4150 See Also 

4151 -------- 

4152 Series.str.lower : Converts all characters to lowercase. 

4153 Series.str.upper : Converts all characters to uppercase. 

4154 Series.str.title : Converts first character of each word to uppercase and 

4155 remaining to lowercase. 

4156 Series.str.capitalize : Converts first character to uppercase and 

4157 remaining to lowercase. 

4158 Series.str.swapcase : Converts uppercase to lowercase and lowercase to 

4159 uppercase. 

4160 Series.str.casefold: Removes all case distinctions in the string. 

4161 

4162 Examples 

4163 -------- 

4164 >>> s = pd.Series(["lower", "CAPITALS", "this is a sentence", "SwApCaSe"]) 

4165 >>> s 

4166 0 lower 

4167 1 CAPITALS 

4168 2 this is a sentence 

4169 3 SwApCaSe 

4170 dtype: str 

4171 

4172 >>> s.str.lower() 

4173 0 lower 

4174 1 capitals 

4175 2 this is a sentence 

4176 3 swapcase 

4177 dtype: str 

4178 

4179 >>> s.str.upper() 

4180 0 LOWER 

4181 1 CAPITALS 

4182 2 THIS IS A SENTENCE 

4183 3 SWAPCASE 

4184 dtype: str 

4185 

4186 >>> s.str.title() 

4187 0 Lower 

4188 1 Capitals 

4189 2 This Is A Sentence 

4190 3 Swapcase 

4191 dtype: str 

4192 

4193 >>> s.str.capitalize() 

4194 0 Lower 

4195 1 Capitals 

4196 2 This is a sentence 

4197 3 Swapcase 

4198 dtype: str 

4199 

4200 >>> s.str.swapcase() 

4201 0 LOWER 

4202 1 capitals 

4203 2 THIS IS A SENTENCE 

4204 3 sWaPcAsE 

4205 dtype: str 

4206 """ 

4207 result = self._data.array._str_capitalize() 

4208 return self._wrap_result(result) 

4209 

4210 @forbid_nonstring_types(["bytes"]) 

4211 def swapcase(self): 

4212 """ 

4213 Convert strings in the Series/Index to be swapcased. 

4214 

4215 Equivalent to :meth:`str.swapcase`. 

4216 

4217 Returns 

4218 ------- 

4219 Series or Index of objects 

4220 A Series or Index where the strings are modified by :meth:`str.swapcase`. 

4221 

4222 See Also 

4223 -------- 

4224 Series.str.lower : Converts all characters to lowercase. 

4225 Series.str.upper : Converts all characters to uppercase. 

4226 Series.str.title : Converts first character of each word to uppercase and 

4227 remaining to lowercase. 

4228 Series.str.capitalize : Converts first character to uppercase and 

4229 remaining to lowercase. 

4230 Series.str.swapcase : Converts uppercase to lowercase and lowercase to 

4231 uppercase. 

4232 Series.str.casefold: Removes all case distinctions in the string. 

4233 

4234 Examples 

4235 -------- 

4236 >>> s = pd.Series(["lower", "CAPITALS", "this is a sentence", "SwApCaSe"]) 

4237 >>> s 

4238 0 lower 

4239 1 CAPITALS 

4240 2 this is a sentence 

4241 3 SwApCaSe 

4242 dtype: str 

4243 

4244 >>> s.str.lower() 

4245 0 lower 

4246 1 capitals 

4247 2 this is a sentence 

4248 3 swapcase 

4249 dtype: str 

4250 

4251 >>> s.str.upper() 

4252 0 LOWER 

4253 1 CAPITALS 

4254 2 THIS IS A SENTENCE 

4255 3 SWAPCASE 

4256 dtype: str 

4257 

4258 >>> s.str.title() 

4259 0 Lower 

4260 1 Capitals 

4261 2 This Is A Sentence 

4262 3 Swapcase 

4263 dtype: str 

4264 

4265 >>> s.str.capitalize() 

4266 0 Lower 

4267 1 Capitals 

4268 2 This is a sentence 

4269 3 Swapcase 

4270 dtype: str 

4271 

4272 >>> s.str.swapcase() 

4273 0 LOWER 

4274 1 capitals 

4275 2 THIS IS A SENTENCE 

4276 3 sWaPcAsE 

4277 dtype: str 

4278 """ 

4279 result = self._data.array._str_swapcase() 

4280 return self._wrap_result(result) 

4281 

4282 @forbid_nonstring_types(["bytes"]) 

4283 def casefold(self): 

4284 """ 

4285 Convert strings in the Series/Index to be casefolded. 

4286 

4287 Equivalent to :meth:`str.casefold`. 

4288 

4289 Returns 

4290 ------- 

4291 Series or Index of objects 

4292 A Series or Index where the strings are modified by :meth:`str.casefold`. 

4293 

4294 See Also 

4295 -------- 

4296 Series.str.lower : Converts all characters to lowercase. 

4297 Series.str.upper : Converts all characters to uppercase. 

4298 Series.str.title : Converts first character of each word to uppercase and 

4299 remaining to lowercase. 

4300 Series.str.capitalize : Converts first character to uppercase and 

4301 remaining to lowercase. 

4302 Series.str.swapcase : Converts uppercase to lowercase and lowercase to 

4303 uppercase. 

4304 Series.str.casefold: Removes all case distinctions in the string. 

4305 

4306 Examples 

4307 -------- 

4308 >>> s = pd.Series(["lower", "CAPITALS", "this is a sentence", "SwApCaSe"]) 

4309 >>> s 

4310 0 lower 

4311 1 CAPITALS 

4312 2 this is a sentence 

4313 3 SwApCaSe 

4314 dtype: str 

4315 

4316 >>> s.str.lower() 

4317 0 lower 

4318 1 capitals 

4319 2 this is a sentence 

4320 3 swapcase 

4321 dtype: str 

4322 

4323 >>> s.str.upper() 

4324 0 LOWER 

4325 1 CAPITALS 

4326 2 THIS IS A SENTENCE 

4327 3 SWAPCASE 

4328 dtype: str 

4329 

4330 >>> s.str.title() 

4331 0 Lower 

4332 1 Capitals 

4333 2 This Is A Sentence 

4334 3 Swapcase 

4335 dtype: str 

4336 

4337 >>> s.str.capitalize() 

4338 0 Lower 

4339 1 Capitals 

4340 2 This is a sentence 

4341 3 Swapcase 

4342 dtype: str 

4343 

4344 >>> s.str.swapcase() 

4345 0 LOWER 

4346 1 capitals 

4347 2 THIS IS A SENTENCE 

4348 3 sWaPcAsE 

4349 dtype: str 

4350 """ 

4351 result = self._data.array._str_casefold() 

4352 return self._wrap_result(result) 

4353 

4354 @forbid_nonstring_types(["bytes"]) 

4355 def isalnum(self): 

4356 """ 

4357 Check whether all characters in each string are alphanumeric. 

4358 

4359 This is equivalent to running the Python string method 

4360 :meth:`str.isalnum` for each element of the Series/Index. If a string 

4361 has zero characters, ``False`` is returned for that check. 

4362 

4363 Returns 

4364 ------- 

4365 Series or Index of bool 

4366 Series or Index of boolean values with the same length as the original 

4367 Series/Index. 

4368 

4369 See Also 

4370 -------- 

4371 Series.str.isalpha : Check whether all characters are alphabetic. 

4372 Series.str.isnumeric : Check whether all characters are numeric. 

4373 Series.str.isdigit : Check whether all characters are digits. 

4374 Series.str.isdecimal : Check whether all characters are decimal. 

4375 Series.str.isspace : Check whether all characters are whitespace. 

4376 Series.str.islower : Check whether all characters are lowercase. 

4377 Series.str.isascii : Check whether all characters are ascii. 

4378 Series.str.isupper : Check whether all characters are uppercase. 

4379 Series.str.istitle : Check whether all characters are titlecase. 

4380 

4381 Examples 

4382 -------- 

4383 >>> s1 = pd.Series(["one", "one1", "1", ""]) 

4384 >>> s1.str.isalnum() 

4385 0 True 

4386 1 True 

4387 2 True 

4388 3 False 

4389 dtype: bool 

4390 

4391 Note that checks against characters mixed with any additional punctuation 

4392 or whitespace will evaluate to false for an alphanumeric check. 

4393 

4394 >>> s2 = pd.Series(["A B", "1.5", "3,000"]) 

4395 >>> s2.str.isalnum() 

4396 0 False 

4397 1 False 

4398 2 False 

4399 dtype: bool 

4400 """ 

4401 result = self._data.array._str_isalnum() 

4402 return self._wrap_result(result, returns_string=False) 

4403 

4404 @forbid_nonstring_types(["bytes"]) 

4405 def isalpha(self): 

4406 """ 

4407 Check whether all characters in each string are alphabetic. 

4408 

4409 This is equivalent to running the Python string method 

4410 :meth:`str.isalpha` for each element of the Series/Index. If a string 

4411 has zero characters, ``False`` is returned for that check. 

4412 

4413 Returns 

4414 ------- 

4415 Series or Index of bool 

4416 Series or Index of boolean values with the same length as the original 

4417 Series/Index. 

4418 

4419 See Also 

4420 -------- 

4421 Series.str.isnumeric : Check whether all characters are numeric. 

4422 Series.str.isalnum : Check whether all characters are alphanumeric. 

4423 Series.str.isdigit : Check whether all characters are digits. 

4424 Series.str.isdecimal : Check whether all characters are decimal. 

4425 Series.str.isspace : Check whether all characters are whitespace. 

4426 Series.str.islower : Check whether all characters are lowercase. 

4427 Series.str.isascii : Check whether all characters are ascii. 

4428 Series.str.isupper : Check whether all characters are uppercase. 

4429 Series.str.istitle : Check whether all characters are titlecase. 

4430 

4431 Examples 

4432 -------- 

4433 

4434 >>> s1 = pd.Series(["one", "one1", "1", ""]) 

4435 >>> s1.str.isalpha() 

4436 0 True 

4437 1 False 

4438 2 False 

4439 3 False 

4440 dtype: bool 

4441 """ 

4442 result = self._data.array._str_isalpha() 

4443 return self._wrap_result(result, returns_string=False) 

4444 

4445 @forbid_nonstring_types(["bytes"]) 

4446 def isdigit(self): 

4447 """ 

4448 Check whether all characters in each string are digits. 

4449 

4450 This is equivalent to running the Python string method 

4451 :meth:`str.isdigit` for each element of the Series/Index. If a string 

4452 has zero characters, ``False`` is returned for that check. 

4453 

4454 Returns 

4455 ------- 

4456 Series or Index of bool 

4457 Series or Index of boolean values with the same length as the original 

4458 Series/Index. 

4459 

4460 See Also 

4461 -------- 

4462 Series.str.isalpha : Check whether all characters are alphabetic. 

4463 Series.str.isnumeric : Check whether all characters are numeric. 

4464 Series.str.isalnum : Check whether all characters are alphanumeric. 

4465 Series.str.isdecimal : Check whether all characters are decimal. 

4466 Series.str.isspace : Check whether all characters are whitespace. 

4467 Series.str.islower : Check whether all characters are lowercase. 

4468 Series.str.isascii : Check whether all characters are ascii. 

4469 Series.str.isupper : Check whether all characters are uppercase. 

4470 Series.str.istitle : Check whether all characters are titlecase. 

4471 

4472 Notes 

4473 ----- 

4474 Similar to ``str.isdecimal`` but also includes special digits, like 

4475 superscripted and subscripted digits in unicode. 

4476 

4477 The exact behavior of this method, i.e. which unicode characters are 

4478 considered as digits, depends on the backend used for string operations, 

4479 and there can be small differences. 

4480 For example, Python considers the ³ superscript character as a digit, but 

4481 not the ⅕ fraction character, while PyArrow considers both as digits. For 

4482 simple (ascii) decimal numbers, the behaviour is consistent. 

4483 

4484 Examples 

4485 -------- 

4486 

4487 >>> s3 = pd.Series(["23", "³", "⅕", ""]) 

4488 >>> s3.str.isdigit() 

4489 0 True 

4490 1 True 

4491 2 True 

4492 3 False 

4493 dtype: bool 

4494 """ 

4495 result = self._data.array._str_isdigit() 

4496 return self._wrap_result(result, returns_string=False) 

4497 

4498 @forbid_nonstring_types(["bytes"]) 

4499 def isspace(self): 

4500 """ 

4501 Check whether all characters in each string are whitespace. 

4502 

4503 This is equivalent to running the Python string method 

4504 :meth:`str.isspace` for each element of the Series/Index. If a string 

4505 has zero characters, ``False`` is returned for that check. 

4506 

4507 Returns 

4508 ------- 

4509 Series or Index of bool 

4510 Series or Index of boolean values with the same length as the original 

4511 Series/Index. 

4512 

4513 See Also 

4514 -------- 

4515 Series.str.isalpha : Check whether all characters are alphabetic. 

4516 Series.str.isnumeric : Check whether all characters are numeric. 

4517 Series.str.isalnum : Check whether all characters are alphanumeric. 

4518 Series.str.isdigit : Check whether all characters are digits. 

4519 Series.str.isdecimal : Check whether all characters are decimal. 

4520 Series.str.islower : Check whether all characters are lowercase. 

4521 Series.str.isascii : Check whether all characters are ascii. 

4522 Series.str.isupper : Check whether all characters are uppercase. 

4523 Series.str.istitle : Check whether all characters are titlecase. 

4524 

4525 Examples 

4526 -------- 

4527 

4528 >>> s4 = pd.Series([" ", "\\t\\r\\n ", ""]) 

4529 >>> s4.str.isspace() 

4530 0 True 

4531 1 True 

4532 2 False 

4533 dtype: bool 

4534 """ 

4535 result = self._data.array._str_isspace() 

4536 return self._wrap_result(result, returns_string=False) 

4537 

4538 @forbid_nonstring_types(["bytes"]) 

4539 def islower(self): 

4540 """ 

4541 Check whether all characters in each string are lowercase. 

4542 

4543 This is equivalent to running the Python string method 

4544 :meth:`str.islower` for each element of the Series/Index. If a string 

4545 has zero characters, ``False`` is returned for that check. 

4546 

4547 Returns 

4548 ------- 

4549 Series or Index of bool 

4550 Series or Index of boolean values with the same length as the original 

4551 Series/Index. 

4552 

4553 See Also 

4554 -------- 

4555 Series.str.isalpha : Check whether all characters are alphabetic. 

4556 Series.str.isnumeric : Check whether all characters are numeric. 

4557 Series.str.isalnum : Check whether all characters are alphanumeric. 

4558 Series.str.isdigit : Check whether all characters are digits. 

4559 Series.str.isdecimal : Check whether all characters are decimal. 

4560 Series.str.isspace : Check whether all characters are whitespace. 

4561 Series.str.isascii : Check whether all characters are ascii. 

4562 Series.str.isupper : Check whether all characters are uppercase. 

4563 Series.str.istitle : Check whether all characters are titlecase. 

4564 

4565 Examples 

4566 -------- 

4567 

4568 >>> s5 = pd.Series(["leopard", "Golden Eagle", "SNAKE", ""]) 

4569 >>> s5.str.islower() 

4570 0 True 

4571 1 False 

4572 2 False 

4573 3 False 

4574 dtype: bool 

4575 """ 

4576 result = self._data.array._str_islower() 

4577 return self._wrap_result(result, returns_string=False) 

4578 

4579 @forbid_nonstring_types(["bytes"]) 

4580 def isascii(self): 

4581 """ 

4582 Check whether all characters in each string are ascii. 

4583 

4584 This is equivalent to running the Python string method 

4585 :meth:`str.isascii` for each element of the Series/Index. If a string 

4586 has zero characters, ``False`` is returned for that check. 

4587 

4588 Returns 

4589 ------- 

4590 Series or Index of bool 

4591 Series or Index of boolean values with the same length as the original 

4592 Series/Index. 

4593 

4594 See Also 

4595 -------- 

4596 Series.str.isalpha : Check whether all characters are alphabetic. 

4597 Series.str.isnumeric : Check whether all characters are numeric. 

4598 Series.str.isalnum : Check whether all characters are alphanumeric. 

4599 Series.str.isdigit : Check whether all characters are digits. 

4600 Series.str.isdecimal : Check whether all characters are decimal. 

4601 Series.str.isspace : Check whether all characters are whitespace. 

4602 Series.str.islower : Check whether all characters are lowercase. 

4603 Series.str.isupper : Check whether all characters are uppercase. 

4604 Series.str.istitle : Check whether all characters are titlecase. 

4605 

4606 Examples 

4607 -------- 

4608 The ``s5.str.isascii`` method checks for whether all characters are ascii 

4609 characters, which includes digits 0-9, capital and lowercase letters A-Z, 

4610 and some other special characters. 

4611 

4612 >>> s5 = pd.Series(["ö", "see123", "hello world", ""]) 

4613 >>> s5.str.isascii() 

4614 0 False 

4615 1 True 

4616 2 True 

4617 3 True 

4618 dtype: bool 

4619 """ 

4620 result = self._data.array._str_isascii() 

4621 return self._wrap_result(result, returns_string=False) 

4622 

4623 @forbid_nonstring_types(["bytes"]) 

4624 def isupper(self): 

4625 """ 

4626 Check whether all characters in each string are uppercase. 

4627 

4628 This is equivalent to running the Python string method 

4629 :meth:`str.isupper` for each element of the Series/Index. If a string 

4630 has zero characters, ``False`` is returned for that check. 

4631 

4632 Returns 

4633 ------- 

4634 Series or Index of bool 

4635 Series or Index of boolean values with the same length as the original 

4636 Series/Index. 

4637 

4638 See Also 

4639 -------- 

4640 Series.str.isalpha : Check whether all characters are alphabetic. 

4641 Series.str.isnumeric : Check whether all characters are numeric. 

4642 Series.str.isalnum : Check whether all characters are alphanumeric. 

4643 Series.str.isdigit : Check whether all characters are digits. 

4644 Series.str.isdecimal : Check whether all characters are decimal. 

4645 Series.str.isspace : Check whether all characters are whitespace. 

4646 Series.str.islower : Check whether all characters are lowercase. 

4647 Series.str.isascii : Check whether all characters are ascii. 

4648 Series.str.istitle : Check whether all characters are titlecase. 

4649 

4650 Examples 

4651 -------- 

4652 

4653 >>> s5 = pd.Series(["leopard", "Golden Eagle", "SNAKE", ""]) 

4654 >>> s5.str.isupper() 

4655 0 False 

4656 1 False 

4657 2 True 

4658 3 False 

4659 dtype: bool 

4660 """ 

4661 result = self._data.array._str_isupper() 

4662 return self._wrap_result(result, returns_string=False) 

4663 

4664 @forbid_nonstring_types(["bytes"]) 

4665 def istitle(self): 

4666 """ 

4667 Check whether all characters in each string are titlecase. 

4668 

4669 This is equivalent to running the Python string method 

4670 :meth:`str.istitle` for each element of the Series/Index. If a string 

4671 has zero characters, ``False`` is returned for that check. 

4672 

4673 Returns 

4674 ------- 

4675 Series or Index of bool 

4676 Series or Index of boolean values with the same length as the original 

4677 Series/Index. 

4678 

4679 See Also 

4680 -------- 

4681 Series.str.isalpha : Check whether all characters are alphabetic. 

4682 Series.str.isnumeric : Check whether all characters are numeric. 

4683 Series.str.isalnum : Check whether all characters are alphanumeric. 

4684 Series.str.isdigit : Check whether all characters are digits. 

4685 Series.str.isdecimal : Check whether all characters are decimal. 

4686 Series.str.isspace : Check whether all characters are whitespace. 

4687 Series.str.islower : Check whether all characters are lowercase. 

4688 Series.str.isascii : Check whether all characters are ascii. 

4689 Series.str.isupper : Check whether all characters are uppercase. 

4690 

4691 Examples 

4692 -------- 

4693 The ``s5.str.istitle`` method checks for whether all words are in title 

4694 case (whether only the first letter of each word is capitalized). Words are 

4695 assumed to be as any sequence of non-numeric characters separated by 

4696 whitespace characters. 

4697 

4698 >>> s5 = pd.Series(["leopard", "Golden Eagle", "SNAKE", ""]) 

4699 >>> s5.str.istitle() 

4700 0 False 

4701 1 True 

4702 2 False 

4703 3 False 

4704 dtype: bool 

4705 """ 

4706 result = self._data.array._str_istitle() 

4707 return self._wrap_result(result, returns_string=False) 

4708 

4709 @forbid_nonstring_types(["bytes"]) 

4710 def isnumeric(self): 

4711 """ 

4712 Check whether all characters in each string are numeric. 

4713 

4714 This is equivalent to running the Python string method 

4715 :meth:`str.isnumeric` for each element of the Series/Index. If a string 

4716 has zero characters, ``False`` is returned for that check. 

4717 

4718 Returns 

4719 ------- 

4720 Series or Index of bool 

4721 Series or Index of boolean values with the same length as the original 

4722 Series/Index. 

4723 

4724 See Also 

4725 -------- 

4726 Series.str.isalpha : Check whether all characters are alphabetic. 

4727 Series.str.isalnum : Check whether all characters are alphanumeric. 

4728 Series.str.isdigit : Check whether all characters are digits. 

4729 Series.str.isdecimal : Check whether all characters are decimal. 

4730 Series.str.isspace : Check whether all characters are whitespace. 

4731 Series.str.islower : Check whether all characters are lowercase. 

4732 Series.str.isascii : Check whether all characters are ascii. 

4733 Series.str.isupper : Check whether all characters are uppercase. 

4734 Series.str.istitle : Check whether all characters are titlecase. 

4735 

4736 Examples 

4737 -------- 

4738 The ``s.str.isnumeric`` method is the same as ``s3.str.isdigit`` but 

4739 also includes other characters that can represent quantities such as 

4740 unicode fractions. 

4741 

4742 >>> s1 = pd.Series(["one", "one1", "1", "", "³", "⅕"]) 

4743 >>> s1.str.isnumeric() 

4744 0 False 

4745 1 False 

4746 2 True 

4747 3 False 

4748 4 True 

4749 5 True 

4750 dtype: bool 

4751 

4752 For a string to be considered numeric, all its characters must have a Unicode 

4753 numeric property matching :py:meth:`str.is_numeric`. As a consequence, 

4754 the following cases are **not** recognized as numeric: 

4755 

4756 - **Decimal numbers** (e.g., "1.1"): due to period ``"."`` 

4757 - **Negative numbers** (e.g., "-5"): due to minus sign ``"-"`` 

4758 - **Scientific notation** (e.g., "1e3"): due to characters like ``"e"`` 

4759 

4760 >>> s2 = pd.Series(["1.1", "-5", "1e3"]) 

4761 >>> s2.str.isnumeric() 

4762 0 False 

4763 1 False 

4764 2 False 

4765 dtype: bool 

4766 """ 

4767 result = self._data.array._str_isnumeric() 

4768 return self._wrap_result(result, returns_string=False) 

4769 

4770 @forbid_nonstring_types(["bytes"]) 

4771 def isdecimal(self): 

4772 """ 

4773 Check whether all characters in each string are decimal. 

4774 

4775 This is equivalent to running the Python string method 

4776 :meth:`str.isdecimal` for each element of the Series/Index. If a string 

4777 has zero characters, ``False`` is returned for that check. 

4778 

4779 Returns 

4780 ------- 

4781 Series or Index of bool 

4782 Series or Index of boolean values with the same length as the original 

4783 Series/Index. 

4784 

4785 See Also 

4786 -------- 

4787 Series.str.isalpha : Check whether all characters are alphabetic. 

4788 Series.str.isnumeric : Check whether all characters are numeric. 

4789 Series.str.isalnum : Check whether all characters are alphanumeric. 

4790 Series.str.isdigit : Check whether all characters are digits. 

4791 Series.str.isspace : Check whether all characters are whitespace. 

4792 Series.str.islower : Check whether all characters are lowercase. 

4793 Series.str.isascii : Check whether all characters are ascii. 

4794 Series.str.isupper : Check whether all characters are uppercase. 

4795 Series.str.istitle : Check whether all characters are titlecase. 

4796 

4797 Examples 

4798 -------- 

4799 The ``s3.str.isdecimal`` method checks for characters used to form 

4800 numbers in base 10. 

4801 

4802 >>> s3 = pd.Series(["23", "³", "⅕", ""]) 

4803 >>> s3.str.isdecimal() 

4804 0 True 

4805 1 False 

4806 2 False 

4807 3 False 

4808 dtype: bool 

4809 """ 

4810 result = self._data.array._str_isdecimal() 

4811 return self._wrap_result(result, returns_string=False) 

4812 

4813 

4814def cat_safe(list_of_columns: list[npt.NDArray[np.object_]], sep: str): 

4815 """ 

4816 Auxiliary function for :meth:`str.cat`. 

4817 

4818 Same signature as cat_core, but handles TypeErrors in concatenation, which 

4819 happen if the arrays in list_of columns have the wrong dtypes or content. 

4820 

4821 Parameters 

4822 ---------- 

4823 list_of_columns : list of numpy arrays 

4824 List of arrays to be concatenated with sep; 

4825 these arrays may not contain NaNs! 

4826 sep : string 

4827 The separator string for concatenating the columns. 

4828 

4829 Returns 

4830 ------- 

4831 nd.array 

4832 The concatenation of list_of_columns with sep. 

4833 """ 

4834 try: 

4835 result = cat_core(list_of_columns, sep) 

4836 except TypeError: 

4837 # if there are any non-string values (wrong dtype or hidden behind 

4838 # object dtype), np.sum will fail; catch and return with better message 

4839 for column in list_of_columns: 

4840 dtype = lib.infer_dtype(column, skipna=True) 

4841 if dtype not in ["string", "empty"]: 

4842 raise TypeError( 

4843 "Concatenation requires list-likes containing only " 

4844 "strings (or missing values). Offending values found in " 

4845 f"column {dtype}" 

4846 ) from None 

4847 return result 

4848 

4849 

4850def cat_core(list_of_columns: list, sep: str): 

4851 """ 

4852 Auxiliary function for :meth:`str.cat` 

4853 

4854 Parameters 

4855 ---------- 

4856 list_of_columns : list of numpy arrays 

4857 List of arrays to be concatenated with sep; 

4858 these arrays may not contain NaNs! 

4859 sep : string 

4860 The separator string for concatenating the columns. 

4861 

4862 Returns 

4863 ------- 

4864 nd.array 

4865 The concatenation of list_of_columns with sep. 

4866 """ 

4867 if sep == "": 

4868 # no need to interleave sep if it is empty 

4869 arr_of_cols = np.asarray(list_of_columns, dtype=object) 

4870 return np.sum(arr_of_cols, axis=0) 

4871 list_with_sep = [sep] * (2 * len(list_of_columns) - 1) 

4872 list_with_sep[::2] = list_of_columns 

4873 arr_with_sep = np.asarray(list_with_sep, dtype=object) 

4874 return np.sum(arr_with_sep, axis=0) 

4875 

4876 

4877def _result_dtype(arr): 

4878 # workaround #27953 

4879 # ideally we just pass `dtype=arr.dtype` unconditionally, but this fails 

4880 # when the list of values is empty. 

4881 from pandas.core.arrays.string_ import StringDtype 

4882 

4883 if isinstance(arr.dtype, (ArrowDtype, StringDtype)): 

4884 return arr.dtype 

4885 return object 

4886 

4887 

4888def _get_single_group_name(regex: re.Pattern) -> Hashable: 

4889 if regex.groupindex: 

4890 return next(iter(regex.groupindex)) 

4891 else: 

4892 return None 

4893 

4894 

4895def get_group_names(regex: re.Pattern) -> list[Hashable] | range: 

4896 """ 

4897 Get named groups from compiled regex. 

4898 

4899 Unnamed groups are numbered. 

4900 

4901 Parameters 

4902 ---------- 

4903 regex : compiled regex 

4904 

4905 Returns 

4906 ------- 

4907 list of column labels 

4908 """ 

4909 rng = range(regex.groups) 

4910 names = {v: k for k, v in regex.groupindex.items()} 

4911 if not names: 

4912 return rng 

4913 result: list[Hashable] = [names.get(1 + i, i) for i in rng] 

4914 arr = np.array(result) 

4915 if arr.dtype.kind == "i" and lib.is_range_indexer(arr, len(arr)): 

4916 return rng 

4917 return result 

4918 

4919 

4920def str_extractall(arr, pat, flags: int = 0) -> DataFrame: 

4921 regex = re.compile(pat, flags=flags) 

4922 # the regex must contain capture groups. 

4923 if regex.groups == 0: 

4924 raise ValueError("pattern contains no capture groups") 

4925 

4926 if isinstance(arr, ABCIndex): 

4927 arr = arr.to_series().reset_index(drop=True).astype(arr.dtype) 

4928 

4929 columns = get_group_names(regex) 

4930 match_list = [] 

4931 index_list = [] 

4932 is_mi = arr.index.nlevels > 1 

4933 

4934 for subject_key, subject in arr.items(): 

4935 if isinstance(subject, str): 

4936 if not is_mi: 

4937 subject_key = (subject_key,) 

4938 

4939 for match_i, match_tuple in enumerate(regex.findall(subject)): 

4940 if isinstance(match_tuple, str): 

4941 match_tuple = (match_tuple,) 

4942 na_tuple = [np.nan if group == "" else group for group in match_tuple] 

4943 match_list.append(na_tuple) 

4944 result_key = (*subject_key, match_i) 

4945 index_list.append(result_key) 

4946 

4947 from pandas import MultiIndex 

4948 

4949 index = MultiIndex.from_tuples(index_list, names=[*arr.index.names, "match"]) 

4950 dtype = _result_dtype(arr) 

4951 

4952 result = arr._constructor_expanddim( 

4953 match_list, index=index, columns=columns, dtype=dtype 

4954 ) 

4955 return result