PageRenderTime 86ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/pandas/core/series.py

http://github.com/pydata/pandas
Python | 5558 lines | 5296 code | 76 blank | 186 comment | 92 complexity | ea8dc81a6f75149e2835496ceafedefc MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. """
  2. Data structure for 1-dimensional cross-sectional and time series data
  3. """
  4. from __future__ import annotations
  5. from textwrap import dedent
  6. from typing import (
  7. IO,
  8. TYPE_CHECKING,
  9. Any,
  10. Callable,
  11. Hashable,
  12. Iterable,
  13. Literal,
  14. Sequence,
  15. Union,
  16. cast,
  17. overload,
  18. )
  19. import warnings
  20. import weakref
  21. import numpy as np
  22. from pandas._config import get_option
  23. from pandas._libs import (
  24. lib,
  25. properties,
  26. reshape,
  27. tslibs,
  28. )
  29. from pandas._libs.lib import no_default
  30. from pandas._typing import (
  31. AggFuncType,
  32. ArrayLike,
  33. Axis,
  34. Dtype,
  35. DtypeObj,
  36. FillnaOptions,
  37. IndexKeyFunc,
  38. SingleManager,
  39. StorageOptions,
  40. TimedeltaConvertibleTypes,
  41. TimestampConvertibleTypes,
  42. ValueKeyFunc,
  43. npt,
  44. )
  45. from pandas.compat.numpy import function as nv
  46. from pandas.errors import InvalidIndexError
  47. from pandas.util._decorators import (
  48. Appender,
  49. Substitution,
  50. deprecate_nonkeyword_arguments,
  51. doc,
  52. )
  53. from pandas.util._validators import (
  54. validate_ascending,
  55. validate_bool_kwarg,
  56. validate_percentile,
  57. )
  58. from pandas.core.dtypes.cast import (
  59. convert_dtypes,
  60. maybe_box_native,
  61. maybe_cast_pointwise_result,
  62. validate_numeric_casting,
  63. )
  64. from pandas.core.dtypes.common import (
  65. ensure_platform_int,
  66. is_dict_like,
  67. is_integer,
  68. is_iterator,
  69. is_list_like,
  70. is_object_dtype,
  71. is_scalar,
  72. pandas_dtype,
  73. validate_all_hashable,
  74. )
  75. from pandas.core.dtypes.generic import ABCDataFrame
  76. from pandas.core.dtypes.inference import is_hashable
  77. from pandas.core.dtypes.missing import (
  78. isna,
  79. na_value_for_dtype,
  80. notna,
  81. remove_na_arraylike,
  82. )
  83. from pandas.core import (
  84. algorithms,
  85. base,
  86. generic,
  87. missing,
  88. nanops,
  89. ops,
  90. )
  91. from pandas.core.accessor import CachedAccessor
  92. from pandas.core.apply import SeriesApply
  93. from pandas.core.arrays import ExtensionArray
  94. from pandas.core.arrays.categorical import CategoricalAccessor
  95. from pandas.core.arrays.sparse import SparseAccessor
  96. import pandas.core.common as com
  97. from pandas.core.construction import (
  98. create_series_with_explicit_dtype,
  99. extract_array,
  100. is_empty_data,
  101. sanitize_array,
  102. )
  103. from pandas.core.generic import NDFrame
  104. from pandas.core.indexers import (
  105. deprecate_ndim_indexing,
  106. unpack_1tuple,
  107. )
  108. from pandas.core.indexes.accessors import CombinedDatetimelikeProperties
  109. from pandas.core.indexes.api import (
  110. CategoricalIndex,
  111. DatetimeIndex,
  112. Float64Index,
  113. Index,
  114. MultiIndex,
  115. PeriodIndex,
  116. TimedeltaIndex,
  117. default_index,
  118. ensure_index,
  119. )
  120. import pandas.core.indexes.base as ibase
  121. from pandas.core.indexing import check_bool_indexer
  122. from pandas.core.internals import (
  123. SingleArrayManager,
  124. SingleBlockManager,
  125. )
  126. from pandas.core.shared_docs import _shared_docs
  127. from pandas.core.sorting import (
  128. ensure_key_mapped,
  129. nargsort,
  130. )
  131. from pandas.core.strings import StringMethods
  132. from pandas.core.tools.datetimes import to_datetime
  133. import pandas.io.formats.format as fmt
  134. import pandas.plotting
  135. if TYPE_CHECKING:
  136. from pandas._typing import (
  137. NumpySorter,
  138. NumpyValueArrayLike,
  139. )
  140. from pandas.core.frame import DataFrame
  141. from pandas.core.groupby.generic import SeriesGroupBy
  142. from pandas.core.resample import Resampler
  143. __all__ = ["Series"]
  144. _shared_doc_kwargs = {
  145. "axes": "index",
  146. "klass": "Series",
  147. "axes_single_arg": "{0 or 'index'}",
  148. "axis": """axis : {0 or 'index'}
  149. Parameter needed for compatibility with DataFrame.""",
  150. "inplace": """inplace : bool, default False
  151. If True, performs operation inplace and returns None.""",
  152. "unique": "np.ndarray",
  153. "duplicated": "Series",
  154. "optional_by": "",
  155. "optional_mapper": "",
  156. "optional_labels": "",
  157. "optional_axis": "",
  158. "replace_iloc": """
  159. This differs from updating with ``.loc`` or ``.iloc``, which require
  160. you to specify a location to update with some value.""",
  161. }
  162. def _coerce_method(converter):
  163. """
  164. Install the scalar coercion methods.
  165. """
  166. def wrapper(self):
  167. if len(self) == 1:
  168. return converter(self.iloc[0])
  169. raise TypeError(f"cannot convert the series to {converter}")
  170. wrapper.__name__ = f"__{converter.__name__}__"
  171. return wrapper
  172. # ----------------------------------------------------------------------
  173. # Series class
  174. class Series(base.IndexOpsMixin, generic.NDFrame):
  175. """
  176. One-dimensional ndarray with axis labels (including time series).
  177. Labels need not be unique but must be a hashable type. The object
  178. supports both integer- and label-based indexing and provides a host of
  179. methods for performing operations involving the index. Statistical
  180. methods from ndarray have been overridden to automatically exclude
  181. missing data (currently represented as NaN).
  182. Operations between Series (+, -, /, \\*, \\*\\*) align values based on their
  183. associated index values-- they need not be the same length. The result
  184. index will be the sorted union of the two indexes.
  185. Parameters
  186. ----------
  187. data : array-like, Iterable, dict, or scalar value
  188. Contains data stored in Series. If data is a dict, argument order is
  189. maintained.
  190. index : array-like or Index (1d)
  191. Values must be hashable and have the same length as `data`.
  192. Non-unique index values are allowed. Will default to
  193. RangeIndex (0, 1, 2, ..., n) if not provided. If data is dict-like
  194. and index is None, then the keys in the data are used as the index. If the
  195. index is not None, the resulting Series is reindexed with the index values.
  196. dtype : str, numpy.dtype, or ExtensionDtype, optional
  197. Data type for the output Series. If not specified, this will be
  198. inferred from `data`.
  199. See the :ref:`user guide <basics.dtypes>` for more usages.
  200. name : str, optional
  201. The name to give to the Series.
  202. copy : bool, default False
  203. Copy input data. Only affects Series or 1d ndarray input. See examples.
  204. Examples
  205. --------
  206. Constructing Series from a dictionary with an Index specified
  207. >>> d = {'a': 1, 'b': 2, 'c': 3}
  208. >>> ser = pd.Series(data=d, index=['a', 'b', 'c'])
  209. >>> ser
  210. a 1
  211. b 2
  212. c 3
  213. dtype: int64
  214. The keys of the dictionary match with the Index values, hence the Index
  215. values have no effect.
  216. >>> d = {'a': 1, 'b': 2, 'c': 3}
  217. >>> ser = pd.Series(data=d, index=['x', 'y', 'z'])
  218. >>> ser
  219. x NaN
  220. y NaN
  221. z NaN
  222. dtype: float64
  223. Note that the Index is first build with the keys from the dictionary.
  224. After this the Series is reindexed with the given Index values, hence we
  225. get all NaN as a result.
  226. Constructing Series from a list with `copy=False`.
  227. >>> r = [1, 2]
  228. >>> ser = pd.Series(r, copy=False)
  229. >>> ser.iloc[0] = 999
  230. >>> r
  231. [1, 2]
  232. >>> ser
  233. 0 999
  234. 1 2
  235. dtype: int64
  236. Due to input data type the Series has a `copy` of
  237. the original data even though `copy=False`, so
  238. the data is unchanged.
  239. Constructing Series from a 1d ndarray with `copy=False`.
  240. >>> r = np.array([1, 2])
  241. >>> ser = pd.Series(r, copy=False)
  242. >>> ser.iloc[0] = 999
  243. >>> r
  244. array([999, 2])
  245. >>> ser
  246. 0 999
  247. 1 2
  248. dtype: int64
  249. Due to input data type the Series has a `view` on
  250. the original data, so
  251. the data is changed as well.
  252. """
  253. _typ = "series"
  254. _HANDLED_TYPES = (Index, ExtensionArray, np.ndarray)
  255. _name: Hashable
  256. _metadata: list[str] = ["name"]
  257. _internal_names_set = {"index"} | generic.NDFrame._internal_names_set
  258. _accessors = {"dt", "cat", "str", "sparse"}
  259. _hidden_attrs = (
  260. base.IndexOpsMixin._hidden_attrs
  261. | generic.NDFrame._hidden_attrs
  262. | frozenset(["compress", "ptp"])
  263. )
  264. # Override cache_readonly bc Series is mutable
  265. # error: Incompatible types in assignment (expression has type "property",
  266. # base class "IndexOpsMixin" defined the type as "Callable[[IndexOpsMixin], bool]")
  267. hasnans = property( # type: ignore[assignment]
  268. # error: "Callable[[IndexOpsMixin], bool]" has no attribute "fget"
  269. base.IndexOpsMixin.hasnans.fget, # type: ignore[attr-defined]
  270. doc=base.IndexOpsMixin.hasnans.__doc__,
  271. )
  272. _mgr: SingleManager
  273. div: Callable[[Series, Any], Series]
  274. rdiv: Callable[[Series, Any], Series]
  275. # ----------------------------------------------------------------------
  276. # Constructors
  277. def __init__(
  278. self,
  279. data=None,
  280. index=None,
  281. dtype: Dtype | None = None,
  282. name=None,
  283. copy: bool = False,
  284. fastpath: bool = False,
  285. ):
  286. if (
  287. isinstance(data, (SingleBlockManager, SingleArrayManager))
  288. and index is None
  289. and dtype is None
  290. and copy is False
  291. ):
  292. # GH#33357 called with just the SingleBlockManager
  293. NDFrame.__init__(self, data)
  294. self.name = name
  295. return
  296. # we are called internally, so short-circuit
  297. if fastpath:
  298. # data is an ndarray, index is defined
  299. if not isinstance(data, (SingleBlockManager, SingleArrayManager)):
  300. manager = get_option("mode.data_manager")
  301. if manager == "block":
  302. data = SingleBlockManager.from_array(data, index)
  303. elif manager == "array":
  304. data = SingleArrayManager.from_array(data, index)
  305. if copy:
  306. data = data.copy()
  307. if index is None:
  308. index = data.index
  309. else:
  310. name = ibase.maybe_extract_name(name, data, type(self))
  311. if is_empty_data(data) and dtype is None:
  312. # gh-17261
  313. warnings.warn(
  314. "The default dtype for empty Series will be 'object' instead "
  315. "of 'float64' in a future version. Specify a dtype explicitly "
  316. "to silence this warning.",
  317. FutureWarning,
  318. stacklevel=2,
  319. )
  320. # uncomment the line below when removing the FutureWarning
  321. # dtype = np.dtype(object)
  322. if index is not None:
  323. index = ensure_index(index)
  324. if data is None:
  325. data = {}
  326. if dtype is not None:
  327. dtype = self._validate_dtype(dtype)
  328. if isinstance(data, MultiIndex):
  329. raise NotImplementedError(
  330. "initializing a Series from a MultiIndex is not supported"
  331. )
  332. elif isinstance(data, Index):
  333. if dtype is not None:
  334. # astype copies
  335. data = data.astype(dtype)
  336. else:
  337. # GH#24096 we need to ensure the index remains immutable
  338. data = data._values.copy()
  339. copy = False
  340. elif isinstance(data, np.ndarray):
  341. if len(data.dtype):
  342. # GH#13296 we are dealing with a compound dtype, which
  343. # should be treated as 2D
  344. raise ValueError(
  345. "Cannot construct a Series from an ndarray with "
  346. "compound dtype. Use DataFrame instead."
  347. )
  348. elif isinstance(data, Series):
  349. if index is None:
  350. index = data.index
  351. else:
  352. data = data.reindex(index, copy=copy)
  353. copy = False
  354. data = data._mgr
  355. elif is_dict_like(data):
  356. data, index = self._init_dict(data, index, dtype)
  357. dtype = None
  358. copy = False
  359. elif isinstance(data, (SingleBlockManager, SingleArrayManager)):
  360. if index is None:
  361. index = data.index
  362. elif not data.index.equals(index) or copy:
  363. # GH#19275 SingleBlockManager input should only be called
  364. # internally
  365. raise AssertionError(
  366. "Cannot pass both SingleBlockManager "
  367. "`data` argument and a different "
  368. "`index` argument. `copy` must be False."
  369. )
  370. elif isinstance(data, ExtensionArray):
  371. pass
  372. else:
  373. data = com.maybe_iterable_to_list(data)
  374. if index is None:
  375. if not is_list_like(data):
  376. data = [data]
  377. index = default_index(len(data))
  378. elif is_list_like(data):
  379. com.require_length_match(data, index)
  380. # create/copy the manager
  381. if isinstance(data, (SingleBlockManager, SingleArrayManager)):
  382. if dtype is not None:
  383. data = data.astype(dtype=dtype, errors="ignore", copy=copy)
  384. elif copy:
  385. data = data.copy()
  386. else:
  387. data = sanitize_array(data, index, dtype, copy)
  388. manager = get_option("mode.data_manager")
  389. if manager == "block":
  390. data = SingleBlockManager.from_array(data, index)
  391. elif manager == "array":
  392. data = SingleArrayManager.from_array(data, index)
  393. generic.NDFrame.__init__(self, data)
  394. self.name = name
  395. self._set_axis(0, index, fastpath=True)
  396. def _init_dict(
  397. self, data, index: Index | None = None, dtype: DtypeObj | None = None
  398. ):
  399. """
  400. Derive the "_mgr" and "index" attributes of a new Series from a
  401. dictionary input.
  402. Parameters
  403. ----------
  404. data : dict or dict-like
  405. Data used to populate the new Series.
  406. index : Index or None, default None
  407. Index for the new Series: if None, use dict keys.
  408. dtype : np.dtype, ExtensionDtype, or None, default None
  409. The dtype for the new Series: if None, infer from data.
  410. Returns
  411. -------
  412. _data : BlockManager for the new Series
  413. index : index for the new Series
  414. """
  415. keys: Index | tuple
  416. # Looking for NaN in dict doesn't work ({np.nan : 1}[float('nan')]
  417. # raises KeyError), so we iterate the entire dict, and align
  418. if data:
  419. # GH:34717, issue was using zip to extract key and values from data.
  420. # using generators in effects the performance.
  421. # Below is the new way of extracting the keys and values
  422. keys = tuple(data.keys())
  423. values = list(data.values()) # Generating list of values- faster way
  424. elif index is not None:
  425. # fastpath for Series(data=None). Just use broadcasting a scalar
  426. # instead of reindexing.
  427. values = na_value_for_dtype(pandas_dtype(dtype), compat=False)
  428. keys = index
  429. else:
  430. keys, values = (), []
  431. # Input is now list-like, so rely on "standard" construction:
  432. # TODO: passing np.float64 to not break anything yet. See GH-17261
  433. s = create_series_with_explicit_dtype(
  434. # error: Argument "index" to "create_series_with_explicit_dtype" has
  435. # incompatible type "Tuple[Any, ...]"; expected "Union[ExtensionArray,
  436. # ndarray, Index, None]"
  437. values,
  438. index=keys, # type: ignore[arg-type]
  439. dtype=dtype,
  440. dtype_if_empty=np.float64,
  441. )
  442. # Now we just make sure the order is respected, if any
  443. if data and index is not None:
  444. s = s.reindex(index, copy=False)
  445. return s._mgr, s.index
  446. # ----------------------------------------------------------------------
  447. @property
  448. def _constructor(self) -> type[Series]:
  449. return Series
  450. @property
  451. def _constructor_expanddim(self) -> type[DataFrame]:
  452. """
  453. Used when a manipulation result has one higher dimension as the
  454. original, such as Series.to_frame()
  455. """
  456. from pandas.core.frame import DataFrame
  457. return DataFrame
  458. # types
  459. @property
  460. def _can_hold_na(self) -> bool:
  461. return self._mgr._can_hold_na
  462. def _set_axis(self, axis: int, labels, fastpath: bool = False) -> None:
  463. """
  464. Override generic, we want to set the _typ here.
  465. This is called from the cython code when we set the `index` attribute
  466. directly, e.g. `series.index = [1, 2, 3]`.
  467. """
  468. if not fastpath:
  469. labels = ensure_index(labels)
  470. if labels._is_all_dates:
  471. deep_labels = labels
  472. if isinstance(labels, CategoricalIndex):
  473. deep_labels = labels.categories
  474. if not isinstance(
  475. deep_labels, (DatetimeIndex, PeriodIndex, TimedeltaIndex)
  476. ):
  477. try:
  478. labels = DatetimeIndex(labels)
  479. # need to set here because we changed the index
  480. if fastpath:
  481. self._mgr.set_axis(axis, labels)
  482. except (tslibs.OutOfBoundsDatetime, ValueError):
  483. # labels may exceeds datetime bounds,
  484. # or not be a DatetimeIndex
  485. pass
  486. if not fastpath:
  487. # The ensure_index call above ensures we have an Index object
  488. self._mgr.set_axis(axis, labels)
  489. # ndarray compatibility
  490. @property
  491. def dtype(self) -> DtypeObj:
  492. """
  493. Return the dtype object of the underlying data.
  494. """
  495. return self._mgr.dtype
  496. @property
  497. def dtypes(self) -> DtypeObj:
  498. """
  499. Return the dtype object of the underlying data.
  500. """
  501. # DataFrame compatibility
  502. return self.dtype
  503. @property
  504. def name(self) -> Hashable:
  505. """
  506. Return the name of the Series.
  507. The name of a Series becomes its index or column name if it is used
  508. to form a DataFrame. It is also used whenever displaying the Series
  509. using the interpreter.
  510. Returns
  511. -------
  512. label (hashable object)
  513. The name of the Series, also the column name if part of a DataFrame.
  514. See Also
  515. --------
  516. Series.rename : Sets the Series name when given a scalar input.
  517. Index.name : Corresponding Index property.
  518. Examples
  519. --------
  520. The Series name can be set initially when calling the constructor.
  521. >>> s = pd.Series([1, 2, 3], dtype=np.int64, name='Numbers')
  522. >>> s
  523. 0 1
  524. 1 2
  525. 2 3
  526. Name: Numbers, dtype: int64
  527. >>> s.name = "Integers"
  528. >>> s
  529. 0 1
  530. 1 2
  531. 2 3
  532. Name: Integers, dtype: int64
  533. The name of a Series within a DataFrame is its column name.
  534. >>> df = pd.DataFrame([[1, 2], [3, 4], [5, 6]],
  535. ... columns=["Odd Numbers", "Even Numbers"])
  536. >>> df
  537. Odd Numbers Even Numbers
  538. 0 1 2
  539. 1 3 4
  540. 2 5 6
  541. >>> df["Even Numbers"].name
  542. 'Even Numbers'
  543. """
  544. return self._name
  545. @name.setter
  546. def name(self, value: Hashable) -> None:
  547. validate_all_hashable(value, error_name=f"{type(self).__name__}.name")
  548. object.__setattr__(self, "_name", value)
  549. @property
  550. def values(self):
  551. """
  552. Return Series as ndarray or ndarray-like depending on the dtype.
  553. .. warning::
  554. We recommend using :attr:`Series.array` or
  555. :meth:`Series.to_numpy`, depending on whether you need
  556. a reference to the underlying data or a NumPy array.
  557. Returns
  558. -------
  559. numpy.ndarray or ndarray-like
  560. See Also
  561. --------
  562. Series.array : Reference to the underlying data.
  563. Series.to_numpy : A NumPy array representing the underlying data.
  564. Examples
  565. --------
  566. >>> pd.Series([1, 2, 3]).values
  567. array([1, 2, 3])
  568. >>> pd.Series(list('aabc')).values
  569. array(['a', 'a', 'b', 'c'], dtype=object)
  570. >>> pd.Series(list('aabc')).astype('category').values
  571. ['a', 'a', 'b', 'c']
  572. Categories (3, object): ['a', 'b', 'c']
  573. Timezone aware datetime data is converted to UTC:
  574. >>> pd.Series(pd.date_range('20130101', periods=3,
  575. ... tz='US/Eastern')).values
  576. array(['2013-01-01T05:00:00.000000000',
  577. '2013-01-02T05:00:00.000000000',
  578. '2013-01-03T05:00:00.000000000'], dtype='datetime64[ns]')
  579. """
  580. return self._mgr.external_values()
  581. @property
  582. def _values(self):
  583. """
  584. Return the internal repr of this data (defined by Block.interval_values).
  585. This are the values as stored in the Block (ndarray or ExtensionArray
  586. depending on the Block class), with datetime64[ns] and timedelta64[ns]
  587. wrapped in ExtensionArrays to match Index._values behavior.
  588. Differs from the public ``.values`` for certain data types, because of
  589. historical backwards compatibility of the public attribute (e.g. period
  590. returns object ndarray and datetimetz a datetime64[ns] ndarray for
  591. ``.values`` while it returns an ExtensionArray for ``._values`` in those
  592. cases).
  593. Differs from ``.array`` in that this still returns the numpy array if
  594. the Block is backed by a numpy array (except for datetime64 and
  595. timedelta64 dtypes), while ``.array`` ensures to always return an
  596. ExtensionArray.
  597. Overview:
  598. dtype | values | _values | array |
  599. ----------- | ------------- | ------------- | ------------- |
  600. Numeric | ndarray | ndarray | PandasArray |
  601. Category | Categorical | Categorical | Categorical |
  602. dt64[ns] | ndarray[M8ns] | DatetimeArray | DatetimeArray |
  603. dt64[ns tz] | ndarray[M8ns] | DatetimeArray | DatetimeArray |
  604. td64[ns] | ndarray[m8ns] | TimedeltaArray| ndarray[m8ns] |
  605. Period | ndarray[obj] | PeriodArray | PeriodArray |
  606. Nullable | EA | EA | EA |
  607. """
  608. return self._mgr.internal_values()
  609. # error: Decorated property not supported
  610. @Appender(base.IndexOpsMixin.array.__doc__) # type: ignore[misc]
  611. @property
  612. def array(self) -> ExtensionArray:
  613. return self._mgr.array_values()
  614. # ops
  615. def ravel(self, order="C"):
  616. """
  617. Return the flattened underlying data as an ndarray.
  618. Returns
  619. -------
  620. numpy.ndarray or ndarray-like
  621. Flattened data of the Series.
  622. See Also
  623. --------
  624. numpy.ndarray.ravel : Return a flattened array.
  625. """
  626. return self._values.ravel(order=order)
  627. def __len__(self) -> int:
  628. """
  629. Return the length of the Series.
  630. """
  631. return len(self._mgr)
  632. def view(self, dtype: Dtype | None = None) -> Series:
  633. """
  634. Create a new view of the Series.
  635. This function will return a new Series with a view of the same
  636. underlying values in memory, optionally reinterpreted with a new data
  637. type. The new data type must preserve the same size in bytes as to not
  638. cause index misalignment.
  639. Parameters
  640. ----------
  641. dtype : data type
  642. Data type object or one of their string representations.
  643. Returns
  644. -------
  645. Series
  646. A new Series object as a view of the same data in memory.
  647. See Also
  648. --------
  649. numpy.ndarray.view : Equivalent numpy function to create a new view of
  650. the same data in memory.
  651. Notes
  652. -----
  653. Series are instantiated with ``dtype=float64`` by default. While
  654. ``numpy.ndarray.view()`` will return a view with the same data type as
  655. the original array, ``Series.view()`` (without specified dtype)
  656. will try using ``float64`` and may fail if the original data type size
  657. in bytes is not the same.
  658. Examples
  659. --------
  660. >>> s = pd.Series([-2, -1, 0, 1, 2], dtype='int8')
  661. >>> s
  662. 0 -2
  663. 1 -1
  664. 2 0
  665. 3 1
  666. 4 2
  667. dtype: int8
  668. The 8 bit signed integer representation of `-1` is `0b11111111`, but
  669. the same bytes represent 255 if read as an 8 bit unsigned integer:
  670. >>> us = s.view('uint8')
  671. >>> us
  672. 0 254
  673. 1 255
  674. 2 0
  675. 3 1
  676. 4 2
  677. dtype: uint8
  678. The views share the same underlying values:
  679. >>> us[0] = 128
  680. >>> s
  681. 0 -128
  682. 1 -1
  683. 2 0
  684. 3 1
  685. 4 2
  686. dtype: int8
  687. """
  688. return self._constructor(
  689. self._values.view(dtype), index=self.index
  690. ).__finalize__(self, method="view")
  691. # ----------------------------------------------------------------------
  692. # NDArray Compat
  693. _HANDLED_TYPES = (Index, ExtensionArray, np.ndarray)
  694. def __array__(self, dtype: npt.DTypeLike | None = None) -> np.ndarray:
  695. """
  696. Return the values as a NumPy array.
  697. Users should not call this directly. Rather, it is invoked by
  698. :func:`numpy.array` and :func:`numpy.asarray`.
  699. Parameters
  700. ----------
  701. dtype : str or numpy.dtype, optional
  702. The dtype to use for the resulting NumPy array. By default,
  703. the dtype is inferred from the data.
  704. Returns
  705. -------
  706. numpy.ndarray
  707. The values in the series converted to a :class:`numpy.ndarray`
  708. with the specified `dtype`.
  709. See Also
  710. --------
  711. array : Create a new array from data.
  712. Series.array : Zero-copy view to the array backing the Series.
  713. Series.to_numpy : Series method for similar behavior.
  714. Examples
  715. --------
  716. >>> ser = pd.Series([1, 2, 3])
  717. >>> np.asarray(ser)
  718. array([1, 2, 3])
  719. For timezone-aware data, the timezones may be retained with
  720. ``dtype='object'``
  721. >>> tzser = pd.Series(pd.date_range('2000', periods=2, tz="CET"))
  722. >>> np.asarray(tzser, dtype="object")
  723. array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
  724. Timestamp('2000-01-02 00:00:00+0100', tz='CET')],
  725. dtype=object)
  726. Or the values may be localized to UTC and the tzinfo discarded with
  727. ``dtype='datetime64[ns]'``
  728. >>> np.asarray(tzser, dtype="datetime64[ns]") # doctest: +ELLIPSIS
  729. array(['1999-12-31T23:00:00.000000000', ...],
  730. dtype='datetime64[ns]')
  731. """
  732. return np.asarray(self._values, dtype)
  733. # ----------------------------------------------------------------------
  734. # Unary Methods
  735. # coercion
  736. __float__ = _coerce_method(float)
  737. __long__ = _coerce_method(int)
  738. __int__ = _coerce_method(int)
  739. # ----------------------------------------------------------------------
  740. # indexers
  741. @property
  742. def axes(self) -> list[Index]:
  743. """
  744. Return a list of the row axis labels.
  745. """
  746. return [self.index]
  747. # ----------------------------------------------------------------------
  748. # Indexing Methods
  749. @Appender(generic.NDFrame.take.__doc__)
  750. def take(self, indices, axis=0, is_copy=None, **kwargs) -> Series:
  751. if is_copy is not None:
  752. warnings.warn(
  753. "is_copy is deprecated and will be removed in a future version. "
  754. "'take' always returns a copy, so there is no need to specify this.",
  755. FutureWarning,
  756. stacklevel=2,
  757. )
  758. nv.validate_take((), kwargs)
  759. indices = ensure_platform_int(indices)
  760. new_index = self.index.take(indices)
  761. new_values = self._values.take(indices)
  762. result = self._constructor(new_values, index=new_index, fastpath=True)
  763. return result.__finalize__(self, method="take")
  764. def _take_with_is_copy(self, indices, axis=0) -> Series:
  765. """
  766. Internal version of the `take` method that sets the `_is_copy`
  767. attribute to keep track of the parent dataframe (using in indexing
  768. for the SettingWithCopyWarning). For Series this does the same
  769. as the public take (it never sets `_is_copy`).
  770. See the docstring of `take` for full explanation of the parameters.
  771. """
  772. return self.take(indices=indices, axis=axis)
  773. def _ixs(self, i: int, axis: int = 0):
  774. """
  775. Return the i-th value or values in the Series by location.
  776. Parameters
  777. ----------
  778. i : int
  779. Returns
  780. -------
  781. scalar (int) or Series (slice, sequence)
  782. """
  783. return self._values[i]
  784. def _slice(self, slobj: slice, axis: int = 0) -> Series:
  785. # axis kwarg is retained for compat with NDFrame method
  786. # _slice is *always* positional
  787. return self._get_values(slobj)
  788. def __getitem__(self, key):
  789. key = com.apply_if_callable(key, self)
  790. if key is Ellipsis:
  791. return self
  792. key_is_scalar = is_scalar(key)
  793. if isinstance(key, (list, tuple)):
  794. key = unpack_1tuple(key)
  795. if is_integer(key) and self.index._should_fallback_to_positional:
  796. return self._values[key]
  797. elif key_is_scalar:
  798. return self._get_value(key)
  799. if is_hashable(key):
  800. # Otherwise index.get_value will raise InvalidIndexError
  801. try:
  802. # For labels that don't resolve as scalars like tuples and frozensets
  803. result = self._get_value(key)
  804. return result
  805. except (KeyError, TypeError):
  806. if isinstance(key, tuple) and isinstance(self.index, MultiIndex):
  807. # We still have the corner case where a tuple is a key
  808. # in the first level of our MultiIndex
  809. return self._get_values_tuple(key)
  810. if is_iterator(key):
  811. key = list(key)
  812. if com.is_bool_indexer(key):
  813. key = check_bool_indexer(self.index, key)
  814. key = np.asarray(key, dtype=bool)
  815. return self._get_values(key)
  816. return self._get_with(key)
  817. def _get_with(self, key):
  818. # other: fancy integer or otherwise
  819. if isinstance(key, slice):
  820. # _convert_slice_indexer to determine if this slice is positional
  821. # or label based, and if the latter, convert to positional
  822. slobj = self.index._convert_slice_indexer(key, kind="getitem")
  823. return self._slice(slobj)
  824. elif isinstance(key, ABCDataFrame):
  825. raise TypeError(
  826. "Indexing a Series with DataFrame is not "
  827. "supported, use the appropriate DataFrame column"
  828. )
  829. elif isinstance(key, tuple):
  830. return self._get_values_tuple(key)
  831. elif not is_list_like(key):
  832. # e.g. scalars that aren't recognized by lib.is_scalar, GH#32684
  833. return self.loc[key]
  834. if not isinstance(key, (list, np.ndarray, ExtensionArray, Series, Index)):
  835. key = list(key)
  836. if isinstance(key, Index):
  837. key_type = key.inferred_type
  838. else:
  839. key_type = lib.infer_dtype(key, skipna=False)
  840. # Note: The key_type == "boolean" case should be caught by the
  841. # com.is_bool_indexer check in __getitem__
  842. if key_type == "integer":
  843. # We need to decide whether to treat this as a positional indexer
  844. # (i.e. self.iloc) or label-based (i.e. self.loc)
  845. if not self.index._should_fallback_to_positional:
  846. return self.loc[key]
  847. else:
  848. return self.iloc[key]
  849. # handle the dup indexing case GH#4246
  850. return self.loc[key]
  851. def _get_values_tuple(self, key):
  852. # mpl hackaround
  853. if com.any_none(*key):
  854. result = self._get_values(key)
  855. deprecate_ndim_indexing(result, stacklevel=5)
  856. return result
  857. if not isinstance(self.index, MultiIndex):
  858. raise KeyError("key of type tuple not found and not a MultiIndex")
  859. # If key is contained, would have returned by now
  860. indexer, new_index = self.index.get_loc_level(key)
  861. return self._constructor(self._values[indexer], index=new_index).__finalize__(
  862. self
  863. )
  864. def _get_values(self, indexer):
  865. try:
  866. new_mgr = self._mgr.getitem_mgr(indexer)
  867. return self._constructor(new_mgr).__finalize__(self)
  868. except ValueError:
  869. # mpl compat if we look up e.g. ser[:, np.newaxis];
  870. # see tests.series.timeseries.test_mpl_compat_hack
  871. # the asarray is needed to avoid returning a 2D DatetimeArray
  872. return np.asarray(self._values[indexer])
  873. def _get_value(self, label, takeable: bool = False):
  874. """
  875. Quickly retrieve single value at passed index label.
  876. Parameters
  877. ----------
  878. label : object
  879. takeable : interpret the index as indexers, default False
  880. Returns
  881. -------
  882. scalar value
  883. """
  884. if takeable:
  885. return self._values[label]
  886. # Similar to Index.get_value, but we do not fall back to positional
  887. loc = self.index.get_loc(label)
  888. return self.index._get_values_for_loc(self, loc, label)
  889. def __setitem__(self, key, value) -> None:
  890. key = com.apply_if_callable(key, self)
  891. cacher_needs_updating = self._check_is_chained_assignment_possible()
  892. if key is Ellipsis:
  893. key = slice(None)
  894. if isinstance(key, slice):
  895. indexer = self.index._convert_slice_indexer(key, kind="getitem")
  896. return self._set_values(indexer, value)
  897. try:
  898. self._set_with_engine(key, value)
  899. except (KeyError, ValueError):
  900. if is_integer(key) and self.index.inferred_type != "integer":
  901. # positional setter
  902. if not self.index._should_fallback_to_positional:
  903. # GH#33469
  904. warnings.warn(
  905. "Treating integers as positional in Series.__setitem__ "
  906. "with a Float64Index is deprecated. In a future version, "
  907. "`series[an_int] = val` will insert a new key into the "
  908. "Series. Use `series.iloc[an_int] = val` to treat the "
  909. "key as positional.",
  910. FutureWarning,
  911. stacklevel=2,
  912. )
  913. # this is equivalent to self._values[key] = value
  914. self._mgr.setitem_inplace(key, value)
  915. else:
  916. # GH#12862 adding a new key to the Series
  917. self.loc[key] = value
  918. except (InvalidIndexError, TypeError) as err:
  919. if isinstance(key, tuple) and not isinstance(self.index, MultiIndex):
  920. # cases with MultiIndex don't get here bc they raise KeyError
  921. raise KeyError(
  922. "key of type tuple not found and not a MultiIndex"
  923. ) from err
  924. if com.is_bool_indexer(key):
  925. key = check_bool_indexer(self.index, key)
  926. key = np.asarray(key, dtype=bool)
  927. if (
  928. is_list_like(value)
  929. and len(value) != len(self)
  930. and not isinstance(value, Series)
  931. and not is_object_dtype(self.dtype)
  932. ):
  933. # Series will be reindexed to have matching length inside
  934. # _where call below
  935. # GH#44265
  936. indexer = key.nonzero()[0]
  937. self._set_values(indexer, value)
  938. return
  939. # otherwise with listlike other we interpret series[mask] = other
  940. # as series[mask] = other[mask]
  941. try:
  942. self._where(~key, value, inplace=True)
  943. except InvalidIndexError:
  944. # test_where_dups
  945. self.iloc[key] = value
  946. return
  947. else:
  948. self._set_with(key, value)
  949. if cacher_needs_updating:
  950. self._maybe_update_cacher()
  951. def _set_with_engine(self, key, value) -> None:
  952. loc = self.index.get_loc(key)
  953. # error: Argument 1 to "validate_numeric_casting" has incompatible type
  954. # "Union[dtype, ExtensionDtype]"; expected "dtype"
  955. validate_numeric_casting(self.dtype, value) # type: ignore[arg-type]
  956. # this is equivalent to self._values[key] = value
  957. self._mgr.setitem_inplace(loc, value)
  958. def _set_with(self, key, value):
  959. # other: fancy integer or otherwise
  960. assert not isinstance(key, tuple)
  961. if is_scalar(key):
  962. key = [key]
  963. elif is_iterator(key):
  964. # Without this, the call to infer_dtype will consume the generator
  965. key = list(key)
  966. key_type = lib.infer_dtype(key, skipna=False)
  967. # Note: key_type == "boolean" should not occur because that
  968. # should be caught by the is_bool_indexer check in __setitem__
  969. if key_type == "integer":
  970. if not self.index._should_fallback_to_positional:
  971. self._set_labels(key, value)
  972. else:
  973. self._set_values(key, value)
  974. else:
  975. self.loc[key] = value
  976. def _set_labels(self, key, value) -> None:
  977. key = com.asarray_tuplesafe(key)
  978. indexer: np.ndarray = self.index.get_indexer(key)
  979. mask = indexer == -1
  980. if mask.any():
  981. raise KeyError(f"{key[mask]} not in index")
  982. self._set_values(indexer, value)
  983. def _set_values(self, key, value) -> None:
  984. if isinstance(key, (Index, Series)):
  985. key = key._values
  986. self._mgr = self._mgr.setitem(indexer=key, value=value)
  987. self._maybe_update_cacher()
  988. def _set_value(self, label, value, takeable: bool = False):
  989. """
  990. Quickly set single value at passed label.
  991. If label is not contained, a new object is created with the label
  992. placed at the end of the result index.
  993. Parameters
  994. ----------
  995. label : object
  996. Partial indexing with MultiIndex not allowed.
  997. value : object
  998. Scalar value.
  999. takeable : interpret the index as indexers, default False
  1000. """
  1001. if not takeable:
  1002. try:
  1003. loc = self.index.get_loc(label)
  1004. except KeyError:
  1005. # set using a non-recursive method
  1006. self.loc[label] = value
  1007. return
  1008. else:
  1009. loc = label
  1010. self._set_values(loc, value)
  1011. # ----------------------------------------------------------------------
  1012. # Lookup Caching
  1013. @property
  1014. def _is_cached(self) -> bool:
  1015. """Return boolean indicating if self is cached or not."""
  1016. return getattr(self, "_cacher", None) is not None
  1017. def _get_cacher(self):
  1018. """return my cacher or None"""
  1019. cacher = getattr(self, "_cacher", None)
  1020. if cacher is not None:
  1021. cacher = cacher[1]()
  1022. return cacher
  1023. def _reset_cacher(self) -> None:
  1024. """
  1025. Reset the cacher.
  1026. """
  1027. if hasattr(self, "_cacher"):
  1028. # should only get here with self.ndim == 1
  1029. del self._cacher
  1030. def _set_as_cached(self, item, cacher) -> None:
  1031. """
  1032. Set the _cacher attribute on the calling object with a weakref to
  1033. cacher.
  1034. """
  1035. self._cacher = (item, weakref.ref(cacher))
  1036. def _clear_item_cache(self) -> None:
  1037. # no-op for Series
  1038. pass
  1039. def _check_is_chained_assignment_possible(self) -> bool:
  1040. """
  1041. See NDFrame._check_is_chained_assignment_possible.__doc__
  1042. """
  1043. if self._is_view and self._is_cached:
  1044. ref = self._get_cacher()
  1045. if ref is not None and ref._is_mixed_type:
  1046. self._check_setitem_copy(t="referent", force=True)
  1047. return True
  1048. return super()._check_is_chained_assignment_possible()
  1049. def _maybe_update_cacher(
  1050. self, clear: bool = False, verify_is_copy: bool = True, inplace: bool = False
  1051. ) -> None:
  1052. """
  1053. See NDFrame._maybe_update_cacher.__doc__
  1054. """
  1055. cacher = getattr(self, "_cacher", None)
  1056. if cacher is not None:
  1057. assert self.ndim == 1
  1058. ref: DataFrame = cacher[1]()
  1059. # we are trying to reference a dead referent, hence
  1060. # a copy
  1061. if ref is None:
  1062. del self._cacher
  1063. elif len(self) == len(ref) and self.name in ref.columns:
  1064. # GH#42530 self.name must be in ref.columns
  1065. # to ensure column still in dataframe
  1066. # otherwise, either self or ref has swapped in new arrays
  1067. ref._maybe_cache_changed(cacher[0], self, inplace=inplace)
  1068. else:
  1069. # GH#33675 we have swapped in a new array, so parent
  1070. # reference to self is now invalid
  1071. ref._item_cache.pop(cacher[0], None)
  1072. super()._maybe_update_cacher(
  1073. clear=clear, verify_is_copy=verify_is_copy, inplace=inplace
  1074. )
  1075. # ----------------------------------------------------------------------
  1076. # Unsorted
  1077. @property
  1078. def _is_mixed_type(self):
  1079. return False
  1080. def repeat(self, repeats, axis=None) -> Series:
  1081. """
  1082. Repeat elements of a Series.
  1083. Returns a new Series where each element of the current Series
  1084. is repeated consecutively a given number of times.
  1085. Parameters
  1086. ----------
  1087. repeats : int or array of ints
  1088. The number of repetitions for each element. This should be a
  1089. non-negative integer. Repeating 0 times will return an empty
  1090. Series.
  1091. axis : None
  1092. Must be ``None``. Has no effect but is accepted for compatibility
  1093. with numpy.
  1094. Returns
  1095. -------
  1096. Series
  1097. Newly created Series with repeated elements.
  1098. See Also
  1099. --------
  1100. Index.repeat : Equivalent function for Index.
  1101. numpy.repeat : Similar method for :class:`numpy.ndarray`.
  1102. Examples
  1103. --------
  1104. >>> s = pd.Series(['a', 'b', 'c'])
  1105. >>> s
  1106. 0 a
  1107. 1 b
  1108. 2 c
  1109. dtype: object
  1110. >>> s.repeat(2)
  1111. 0 a
  1112. 0 a
  1113. 1 b
  1114. 1 b
  1115. 2 c
  1116. 2 c
  1117. dtype: object
  1118. >>> s.repeat([1, 2, 3])
  1119. 0 a
  1120. 1 b
  1121. 1 b
  1122. 2 c
  1123. 2 c
  1124. 2 c
  1125. dtype: object
  1126. """
  1127. nv.validate_repeat((), {"axis": axis})
  1128. new_index = self.index.repeat(repeats)
  1129. new_values = self._values.repeat(repeats)
  1130. return self._constructor(new_values, index=new_index).__finalize__(
  1131. self, method="repeat"
  1132. )
  1133. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "level"])
  1134. def reset_index(self, level=None, drop=False, name=lib.no_default, inplace=False):
  1135. """
  1136. Generate a new DataFrame or Series with the index reset.
  1137. This is useful when the index needs to be treated as a column, or
  1138. when the index is meaningless and needs to be reset to the default
  1139. before another operation.
  1140. Parameters
  1141. ----------
  1142. level : int, str, tuple, or list, default optional
  1143. For a Series with a MultiIndex, only remove the specified levels
  1144. from the index. Removes all levels by default.
  1145. drop : bool, default False
  1146. Just reset the index, without inserting it as a column in
  1147. the new DataFrame.
  1148. name : object, optional
  1149. The name to use for the column containing the original Series
  1150. values. Uses ``self.name`` by default. This argument is ignored
  1151. when `drop` is True.
  1152. inplace : bool, default False
  1153. Modify the Series in place (do not create a new object).
  1154. Returns
  1155. -------
  1156. Series or DataFrame or None
  1157. When `drop` is False (the default), a DataFrame is returned.
  1158. The newly created columns will come first in the DataFrame,
  1159. followed by the original Series values.
  1160. When `drop` is True, a `Series` is returned.
  1161. In either case, if ``inplace=True``, no value is returned.
  1162. See Also
  1163. --------
  1164. DataFrame.reset_index: Analogous function for DataFrame.
  1165. Examples
  1166. --------
  1167. >>> s = pd.Series([1, 2, 3, 4], name='foo',
  1168. ... index=pd.Index(['a', 'b', 'c', 'd'], name='idx'))
  1169. Generate a DataFrame with default index.
  1170. >>> s.reset_index()
  1171. idx foo
  1172. 0 a 1
  1173. 1 b 2
  1174. 2 c 3
  1175. 3 d 4
  1176. To specify the name of the new column use `name`.
  1177. >>> s.reset_index(name='values')
  1178. idx values
  1179. 0 a 1
  1180. 1 b 2
  1181. 2 c 3
  1182. 3 d 4
  1183. To generate a new Series with the default set `drop` to True.
  1184. >>> s.reset_index(drop=True)
  1185. 0 1
  1186. 1 2
  1187. 2 3
  1188. 3 4
  1189. Name: foo, dtype: int64
  1190. To update the Series in place, without generating a new one
  1191. set `inplace` to True. Note that it also requires ``drop=True``.
  1192. >>> s.reset_index(inplace=True, drop=True)
  1193. >>> s
  1194. 0 1
  1195. 1 2
  1196. 2 3
  1197. 3 4
  1198. Name: foo, dtype: int64
  1199. The `level` parameter is interesting for Series with a multi-level
  1200. index.
  1201. >>> arrays = [np.array(['bar', 'bar', 'baz', 'baz']),
  1202. ... np.array(['one', 'two', 'one', 'two'])]
  1203. >>> s2 = pd.Series(
  1204. ... range(4), name='foo',
  1205. ... index=pd.MultiIndex.from_arrays(arrays,
  1206. ... names=['a', 'b']))
  1207. To remove a specific level from the Index, use `level`.
  1208. >>> s2.reset_index(level='a')
  1209. a foo
  1210. b
  1211. one bar 0
  1212. two bar 1
  1213. one baz 2
  1214. two baz 3
  1215. If `level` is not set, all levels are removed from the Index.
  1216. >>> s2.reset_index()
  1217. a b foo
  1218. 0 bar one 0
  1219. 1 bar two 1
  1220. 2 baz one 2
  1221. 3 baz two 3
  1222. """
  1223. inplace = validate_bool_kwarg(inplace, "inplace")
  1224. if drop:
  1225. if name is lib.no_default:
  1226. name = self.name
  1227. new_index = default_index(len(self))
  1228. if level is not None:
  1229. if not isinstance(level, (tuple, list)):
  1230. level = [level]
  1231. level = [self.index._get_level_number(lev) for lev in level]
  1232. if len(level) < self.index.nlevels:
  1233. new_index = self.index.droplevel(level)
  1234. if inplace:
  1235. self.index = new_index
  1236. # set name if it was passed, otherwise, keep the previous name
  1237. self.name = name or self.name
  1238. else:
  1239. return self._constructor(
  1240. self._values.copy(), index=new_index
  1241. ).__finalize__(self, method="reset_index")
  1242. elif inplace:
  1243. raise TypeError(
  1244. "Cannot reset_index inplace on a Series to create a DataFrame"
  1245. )
  1246. else:
  1247. if name is lib.no_default:
  1248. # For backwards compatibility, keep columns as [0] instead of
  1249. # [None] when self.name is None
  1250. if self.name is None:
  1251. name = 0
  1252. else:
  1253. name = self.name
  1254. df = self.to_frame(name)
  1255. return df.reset_index(level=level, drop=drop)
  1256. # ----------------------------------------------------------------------
  1257. # Rendering Methods
  1258. def __repr__(self) -> str:
  1259. """
  1260. Return a string representation for a particular Series.
  1261. """
  1262. repr_params = fmt.get_series_repr_params()
  1263. return self.to_string(**repr_params)
  1264. def to_string(
  1265. self,
  1266. buf=None,
  1267. na_rep="NaN",
  1268. float_format=None,
  1269. header=True,
  1270. index=True,
  1271. length=False,
  1272. dtype=False,
  1273. name=False,
  1274. max_rows=None,
  1275. min_rows=None,
  1276. ):
  1277. """
  1278. Render a string representation of the Series.
  1279. Parameters
  1280. ----------
  1281. buf : StringIO-like, optional
  1282. Buffer to write to.
  1283. na_rep : str, optional
  1284. String representation of NaN to use, default 'NaN'.
  1285. float_format : one-parameter function, optional
  1286. Formatter function to apply to columns' elements if they are
  1287. floats, default None.
  1288. header : bool, default True
  1289. Add the Series header (index name).
  1290. index : bool, optional
  1291. Add index (row) labels, default True.
  1292. length : bool, default False
  1293. Add the Series length.
  1294. dtype : bool, default False
  1295. Add the Series dtype.
  1296. name : bool, default False
  1297. Add the Series name if not None.
  1298. max_rows : int, optional
  1299. Maximum number of rows to show before truncating. If None, show
  1300. all.
  1301. min_rows : int, optional
  1302. The number of rows to display in a truncated repr (when number
  1303. of rows is above `max_rows`).
  1304. Returns
  1305. -------
  1306. str or None
  1307. String representation of Series if ``buf=None``, otherwise None.
  1308. """
  1309. formatter = fmt.SeriesFormatter(
  1310. self,
  1311. name=name,
  1312. length=length,
  1313. header=header,
  1314. index=index,
  1315. dtype=dtype,
  1316. na_rep=na_rep,
  1317. float_format=float_format,
  1318. min_rows=min_rows,
  1319. max_rows=max_rows,
  1320. )
  1321. result = formatter.to_string()
  1322. # catch contract violations
  1323. if not isinstance(result, str):
  1324. raise AssertionError(
  1325. "result must be of type str, type "
  1326. f"of result is {repr(type(result).__name__)}"
  1327. )
  1328. if buf is None:
  1329. return result
  1330. else:
  1331. try:
  1332. buf.write(result)
  1333. except AttributeError:
  1334. with open(buf, "w") as f:
  1335. f.write(result)
  1336. @doc(
  1337. klass=_shared_doc_kwargs["klass"],
  1338. storage_options=generic._shared_docs["storage_options"],
  1339. examples=dedent(
  1340. """Examples
  1341. --------
  1342. >>> s = pd.Series(["elk", "pig", "dog", "quetzal"], name="animal")
  1343. >>> print(s.to_markdown())
  1344. | | animal |
  1345. |---:|:---------|
  1346. | 0 | elk |
  1347. | 1 | pig |
  1348. | 2 | dog |
  1349. | 3 | quetzal |
  1350. Output markdown with a tabulate option.
  1351. >>> print(s.to_markdown(tablefmt="grid"))
  1352. +----+----------+
  1353. | | animal |
  1354. +====+==========+
  1355. | 0 | elk |
  1356. +----+----------+
  1357. | 1 | pig |
  1358. +----+----------+
  1359. | 2 | dog |
  1360. +----+----------+
  1361. | 3 | quetzal |
  1362. +----+----------+"""
  1363. ),
  1364. )
  1365. def to_markdown(
  1366. self,
  1367. buf: IO[str] | None = None,
  1368. mode: str = "wt",
  1369. index: bool = True,
  1370. storage_options: StorageOptions = None,
  1371. **kwargs,
  1372. ) -> str | None:
  1373. """
  1374. Print {klass} in Markdown-friendly format.
  1375. .. versionadded:: 1.0.0
  1376. Parameters
  1377. ----------
  1378. buf : str, Path or StringIO-like, optional, default None
  1379. Buffer to write to. If None, the output is returned as a string.
  1380. mode : str, optional
  1381. Mode in which file is opened, "wt" by default.
  1382. index : bool, optional, default True
  1383. Add index (row) labels.
  1384. .. versionadded:: 1.1.0
  1385. {storage_options}
  1386. .. versionadded:: 1.2.0
  1387. **kwargs
  1388. These parameters will be passed to `tabulate \
  1389. <https://pypi.org/project/tabulate>`_.
  1390. Returns
  1391. -------
  1392. str
  1393. {klass} in Markdown-friendly format.
  1394. Notes
  1395. -----
  1396. Requires the `tabulate <https://pypi.org/project/tabulate>`_ package.
  1397. {examples}
  1398. """
  1399. return self.to_frame().to_markdown(
  1400. buf, mode, index, storage_options=storage_options, **kwargs
  1401. )
  1402. # ----------------------------------------------------------------------
  1403. def items(self) -> Iterable[tuple[Hashable, Any]]:
  1404. """
  1405. Lazily iterate over (index, value) tuples.
  1406. This method returns an iterable tuple (index, value). This is
  1407. convenient if you want to create a lazy iterator.
  1408. Returns
  1409. -------
  1410. iterable
  1411. Iterable of tuples containing the (index, value) pairs from a
  1412. Series.
  1413. See Also
  1414. --------
  1415. DataFrame.items : Iterate over (column name, Series) pairs.
  1416. DataFrame.iterrows : Iterate over DataFrame rows as (index, Series) pairs.
  1417. Examples
  1418. --------
  1419. >>> s = pd.Series(['A', 'B', 'C'])
  1420. >>> for index, value in s.items():
  1421. ... print(f"Index : {index}, Value : {value}")
  1422. Index : 0, Value : A
  1423. Index : 1, Value : B
  1424. Index : 2, Value : C
  1425. """
  1426. return zip(iter(self.index), iter(self))
  1427. @Appender(items.__doc__)
  1428. def iteritems(self) -> Iterable[tuple[Hashable, Any]]:
  1429. return self.items()
  1430. # ----------------------------------------------------------------------
  1431. # Misc public methods
  1432. def keys(self) -> Index:
  1433. """
  1434. Return alias for index.
  1435. Returns
  1436. -------
  1437. Index
  1438. Index of the Series.
  1439. """
  1440. return self.index
  1441. def to_dict(self, into=dict):
  1442. """
  1443. Convert Series to {label -> value} dict or dict-like object.
  1444. Parameters
  1445. ----------
  1446. into : class, default dict
  1447. The collections.abc.Mapping subclass to use as the return
  1448. object. Can be the actual class or an empty
  1449. instance of the mapping type you want. If you want a
  1450. collections.defaultdict, you must pass it initialized.
  1451. Returns
  1452. -------
  1453. collections.abc.Mapping
  1454. Key-value representation of Series.
  1455. Examples
  1456. --------
  1457. >>> s = pd.Series([1, 2, 3, 4])
  1458. >>> s.to_dict()
  1459. {0: 1, 1: 2, 2: 3, 3: 4}
  1460. >>> from collections import OrderedDict, defaultdict
  1461. >>> s.to_dict(OrderedDict)
  1462. OrderedDict([(0, 1), (1, 2), (2, 3), (3, 4)])
  1463. >>> dd = defaultdict(list)
  1464. >>> s.to_dict(dd)
  1465. defaultdict(<class 'list'>, {0: 1, 1: 2, 2: 3, 3: 4})
  1466. """
  1467. # GH16122
  1468. into_c = com.standardize_mapping(into)
  1469. return into_c((k, maybe_box_native(v)) for k, v in self.items())
  1470. def to_frame(self, name: Hashable = lib.no_default) -> DataFrame:
  1471. """
  1472. Convert Series to DataFrame.
  1473. Parameters
  1474. ----------
  1475. name : object, default None
  1476. The passed name should substitute for the series name (if it has
  1477. one).
  1478. Returns
  1479. -------
  1480. DataFrame
  1481. DataFrame representation of Series.
  1482. Examples
  1483. --------
  1484. >>> s = pd.Series(["a", "b", "c"],
  1485. ... name="vals")
  1486. >>> s.to_frame()
  1487. vals
  1488. 0 a
  1489. 1 b
  1490. 2 c
  1491. """
  1492. columns: Index
  1493. if name is lib.no_default:
  1494. name = self.name
  1495. if name is None:
  1496. # default to [0], same as we would get with DataFrame(self)
  1497. columns = default_index(1)
  1498. else:
  1499. columns = Index([name])
  1500. else:
  1501. columns = Index([name])
  1502. mgr = self._mgr.to_2d_mgr(columns)
  1503. return self._constructor_expanddim(mgr)
  1504. def _set_name(self, name, inplace=False) -> Series:
  1505. """
  1506. Set the Series name.
  1507. Parameters
  1508. ----------
  1509. name : str
  1510. inplace : bool
  1511. Whether to modify `self` directly or return a copy.
  1512. """
  1513. inplace = validate_bool_kwarg(inplace, "inplace")
  1514. ser = self if inplace else self.copy()
  1515. ser.name = name
  1516. return ser
  1517. @Appender(
  1518. """
  1519. Examples
  1520. --------
  1521. >>> ser = pd.Series([390., 350., 30., 20.],
  1522. ... index=['Falcon', 'Falcon', 'Parrot', 'Parrot'], name="Max Speed")
  1523. >>> ser
  1524. Falcon 390.0
  1525. Falcon 350.0
  1526. Parrot 30.0
  1527. Parrot 20.0
  1528. Name: Max Speed, dtype: float64
  1529. >>> ser.groupby(["a", "b", "a", "b"]).mean()
  1530. a 210.0
  1531. b 185.0
  1532. Name: Max Speed, dtype: float64
  1533. >>> ser.groupby(level=0).mean()
  1534. Falcon 370.0
  1535. Parrot 25.0
  1536. Name: Max Speed, dtype: float64
  1537. >>> ser.groupby(ser > 100).mean()
  1538. Max Speed
  1539. False 25.0
  1540. True 370.0
  1541. Name: Max Speed, dtype: float64
  1542. **Grouping by Indexes**
  1543. We can groupby different levels of a hierarchical index
  1544. using the `level` parameter:
  1545. >>> arrays = [['Falcon', 'Falcon', 'Parrot', 'Parrot'],
  1546. ... ['Captive', 'Wild', 'Captive', 'Wild']]
  1547. >>> index = pd.MultiIndex.from_arrays(arrays, names=('Animal', 'Type'))
  1548. >>> ser = pd.Series([390., 350., 30., 20.], index=index, name="Max Speed")
  1549. >>> ser
  1550. Animal Type
  1551. Falcon Captive 390.0
  1552. Wild 350.0
  1553. Parrot Captive 30.0
  1554. Wild 20.0
  1555. Name: Max Speed, dtype: float64
  1556. >>> ser.groupby(level=0).mean()
  1557. Animal
  1558. Falcon 370.0
  1559. Parrot 25.0
  1560. Name: Max Speed, dtype: float64
  1561. >>> ser.groupby(level="Type").mean()
  1562. Type
  1563. Captive 210.0
  1564. Wild 185.0
  1565. Name: Max Speed, dtype: float64
  1566. We can also choose to include `NA` in group keys or not by defining
  1567. `dropna` parameter, the default setting is `True`:
  1568. >>> ser = pd.Series([1, 2, 3, 3], index=["a", 'a', 'b', np.nan])
  1569. >>> ser.groupby(level=0).sum()
  1570. a 3
  1571. b 3
  1572. dtype: int64
  1573. >>> ser.groupby(level=0, dropna=False).sum()
  1574. a 3
  1575. b 3
  1576. NaN 3
  1577. dtype: int64
  1578. >>> arrays = ['Falcon', 'Falcon', 'Parrot', 'Parrot']
  1579. >>> ser = pd.Series([390., 350., 30., 20.], index=arrays, name="Max Speed")
  1580. >>> ser.groupby(["a", "b", "a", np.nan]).mean()
  1581. a 210.0
  1582. b 350.0
  1583. Name: Max Speed, dtype: float64
  1584. >>> ser.groupby(["a", "b", "a", np.nan], dropna=False).mean()
  1585. a 210.0
  1586. b 350.0
  1587. NaN 20.0
  1588. Name: Max Speed, dtype: float64
  1589. """
  1590. )
  1591. @Appender(generic._shared_docs["groupby"] % _shared_doc_kwargs)
  1592. def groupby(
  1593. self,
  1594. by=None,
  1595. axis=0,
  1596. level=None,
  1597. as_index: bool = True,
  1598. sort: bool = True,
  1599. group_keys: bool = True,
  1600. squeeze: bool | lib.NoDefault = no_default,
  1601. observed: bool = False,
  1602. dropna: bool = True,
  1603. ) -> SeriesGroupBy:
  1604. from pandas.core.groupby.generic import SeriesGroupBy
  1605. if squeeze is not no_default:
  1606. warnings.warn(
  1607. (
  1608. "The `squeeze` parameter is deprecated and "
  1609. "will be removed in a future version."
  1610. ),
  1611. FutureWarning,
  1612. stacklevel=2,
  1613. )
  1614. else:
  1615. squeeze = False
  1616. if level is None and by is None:
  1617. raise TypeError("You have to supply one of 'by' and 'level'")
  1618. axis = self._get_axis_number(axis)
  1619. # error: Argument "squeeze" to "SeriesGroupBy" has incompatible type
  1620. # "Union[bool, NoDefault]"; expected "bool"
  1621. return SeriesGroupBy(
  1622. obj=self,
  1623. keys=by,
  1624. axis=axis,
  1625. level=level,
  1626. as_index=as_index,
  1627. sort=sort,
  1628. group_keys=group_keys,
  1629. squeeze=squeeze, # type: ignore[arg-type]
  1630. observed=observed,
  1631. dropna=dropna,
  1632. )
  1633. # ----------------------------------------------------------------------
  1634. # Statistics, overridden ndarray methods
  1635. # TODO: integrate bottleneck
  1636. def count(self, level=None):
  1637. """
  1638. Return number of non-NA/null observations in the Series.
  1639. Parameters
  1640. ----------
  1641. level : int or level name, default None
  1642. If the axis is a MultiIndex (hierarchical), count along a
  1643. particular level, collapsing into a smaller Series.
  1644. Returns
  1645. -------
  1646. int or Series (if level specified)
  1647. Number of non-null values in the Series.
  1648. See Also
  1649. --------
  1650. DataFrame.count : Count non-NA cells for each column or row.
  1651. Examples
  1652. --------
  1653. >>> s = pd.Series([0.0, 1.0, np.nan])
  1654. >>> s.count()
  1655. 2
  1656. """
  1657. if level is None:
  1658. return notna(self._values).sum().astype("int64")
  1659. else:
  1660. warnings.warn(
  1661. "Using the level keyword in DataFrame and Series aggregations is "
  1662. "deprecated and will be removed in a future version. Use groupby "
  1663. "instead. ser.count(level=1) should use ser.groupby(level=1).count().",
  1664. FutureWarning,
  1665. stacklevel=2,
  1666. )
  1667. if not isinstance(self.index, MultiIndex):
  1668. raise ValueError("Series.count level is only valid with a MultiIndex")
  1669. index = self.index
  1670. assert isinstance(index, MultiIndex) # for mypy
  1671. if isinstance(level, str):
  1672. level = index._get_level_number(level)
  1673. lev = index.levels[level]
  1674. level_codes = np.array(index.codes[level], subok=False, copy=True)
  1675. mask = level_codes == -1
  1676. if mask.any():
  1677. level_codes[mask] = cnt = len(lev)
  1678. lev = lev.insert(cnt, lev._na_value)
  1679. obs = level_codes[notna(self._values)]
  1680. out = np.bincount(obs, minlength=len(lev) or None)
  1681. return self._constructor(out, index=lev, dtype="int64").__finalize__(
  1682. self, method="count"
  1683. )
  1684. def mode(self, dropna=True) -> Series:
  1685. """
  1686. Return the mode(s) of the Series.
  1687. The mode is the value that appears most often. There can be multiple modes.
  1688. Always returns Series even if only one value is returned.
  1689. Parameters
  1690. ----------
  1691. dropna : bool, default True
  1692. Don't consider counts of NaN/NaT.
  1693. Returns
  1694. -------
  1695. Series
  1696. Modes of the Series in sorted order.
  1697. """
  1698. # TODO: Add option for bins like value_counts()
  1699. return algorithms.mode(self, dropna=dropna)
  1700. def unique(self) -> ArrayLike:
  1701. """
  1702. Return unique values of Series object.
  1703. Uniques are returned in order of appearance. Hash table-based unique,
  1704. therefore does NOT sort.
  1705. Returns
  1706. -------
  1707. ndarray or ExtensionArray
  1708. The unique values returned as a NumPy array. See Notes.
  1709. See Also
  1710. --------
  1711. unique : Top-level unique method for any 1-d array-like object.
  1712. Index.unique : Return Index with unique values from an Index object.
  1713. Notes
  1714. -----
  1715. Returns the unique values as a NumPy array. In case of an
  1716. extension-array backed Series, a new
  1717. :class:`~api.extensions.ExtensionArray` of that type with just
  1718. the unique values is returned. This includes
  1719. * Categorical
  1720. * Period
  1721. * Datetime with Timezone
  1722. * Interval
  1723. * Sparse
  1724. * IntegerNA
  1725. See Examples section.
  1726. Examples
  1727. --------
  1728. >>> pd.Series([2, 1, 3, 3], name='A').unique()
  1729. array([2, 1, 3])
  1730. >>> pd.Series([pd.Timestamp('2016-01-01') for _ in range(3)]).unique()
  1731. array(['2016-01-01T00:00:00.000000000'], dtype='datetime64[ns]')
  1732. >>> pd.Series([pd.Timestamp('2016-01-01', tz='US/Eastern')
  1733. ... for _ in range(3)]).unique()
  1734. <DatetimeArray>
  1735. ['2016-01-01 00:00:00-05:00']
  1736. Length: 1, dtype: datetime64[ns, US/Eastern]
  1737. An Categorical will return categories in the order of
  1738. appearance and with the same dtype.
  1739. >>> pd.Series(pd.Categorical(list('baabc'))).unique()
  1740. ['b', 'a', 'c']
  1741. Categories (3, object): ['a', 'b', 'c']
  1742. >>> pd.Series(pd.Categorical(list('baabc'), categories=list('abc'),
  1743. ... ordered=True)).unique()
  1744. ['b', 'a', 'c']
  1745. Categories (3, object): ['a' < 'b' < 'c']
  1746. """
  1747. return super().unique()
  1748. @overload
  1749. def drop_duplicates(self, keep=..., inplace: Literal[False] = ...) -> Series:
  1750. ...
  1751. @overload
  1752. def drop_duplicates(self, keep, inplace: Literal[True]) -> None:
  1753. ...
  1754. @overload
  1755. def drop_duplicates(self, *, inplace: Literal[True]) -> None:
  1756. ...
  1757. @overload
  1758. def drop_duplicates(self, keep=..., inplace: bool = ...) -> Series | None:
  1759. ...
  1760. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
  1761. def drop_duplicates(self, keep="first", inplace=False) -> Series | None:
  1762. """
  1763. Return Series with duplicate values removed.
  1764. Parameters
  1765. ----------
  1766. keep : {'first', 'last', ``False``}, default 'first'
  1767. Method to handle dropping duplicates:
  1768. - 'first' : Drop duplicates except for the first occurrence.
  1769. - 'last' : Drop duplicates except for the last occurrence.
  1770. - ``False`` : Drop all duplicates.
  1771. inplace : bool, default ``False``
  1772. If ``True``, performs operation inplace and returns None.
  1773. Returns
  1774. -------
  1775. Series or None
  1776. Series with duplicates dropped or None if ``inplace=True``.
  1777. See Also
  1778. --------
  1779. Index.drop_duplicates : Equivalent method on Index.
  1780. DataFrame.drop_duplicates : Equivalent method on DataFrame.
  1781. Series.duplicated : Related method on Series, indicating duplicate
  1782. Series values.
  1783. Examples
  1784. --------
  1785. Generate a Series with duplicated entries.
  1786. >>> s = pd.Series(['lama', 'cow', 'lama', 'beetle', 'lama', 'hippo'],
  1787. ... name='animal')
  1788. >>> s
  1789. 0 lama
  1790. 1 cow
  1791. 2 lama
  1792. 3 beetle
  1793. 4 lama
  1794. 5 hippo
  1795. Name: animal, dtype: object
  1796. With the 'keep' parameter, the selection behaviour of duplicated values
  1797. can be changed. The value 'first' keeps the first occurrence for each
  1798. set of duplicated entries. The default value of keep is 'first'.
  1799. >>> s.drop_duplicates()
  1800. 0 lama
  1801. 1 cow
  1802. 3 beetle
  1803. 5 hippo
  1804. Name: animal, dtype: object
  1805. The value 'last' for parameter 'keep' keeps the last occurrence for
  1806. each set of duplicated entries.
  1807. >>> s.drop_duplicates(keep='last')
  1808. 1 cow
  1809. 3 beetle
  1810. 4 lama
  1811. 5 hippo
  1812. Name: animal, dtype: object
  1813. The value ``False`` for parameter 'keep' discards all sets of
  1814. duplicated entries. Setting the value of 'inplace' to ``True`` performs
  1815. the operation inplace and returns ``None``.
  1816. >>> s.drop_duplicates(keep=False, inplace=True)
  1817. >>> s
  1818. 1 cow
  1819. 3 beetle
  1820. 5 hippo
  1821. Name: animal, dtype: object
  1822. """
  1823. inplace = validate_bool_kwarg(inplace, "inplace")
  1824. result = super().drop_duplicates(keep=keep)
  1825. if inplace:
  1826. self._update_inplace(result)
  1827. return None
  1828. else:
  1829. return result
  1830. def duplicated(self, keep="first") -> Series:
  1831. """
  1832. Indicate duplicate Series values.
  1833. Duplicated values are indicated as ``True`` values in the resulting
  1834. Series. Either all duplicates, all except the first or all except the
  1835. last occurrence of duplicates can be indicated.
  1836. Parameters
  1837. ----------
  1838. keep : {'first', 'last', False}, default 'first'
  1839. Method to handle dropping duplicates:
  1840. - 'first' : Mark duplicates as ``True`` except for the first
  1841. occurrence.
  1842. - 'last' : Mark duplicates as ``True`` except for the last
  1843. occurrence.
  1844. - ``False`` : Mark all duplicates as ``True``.
  1845. Returns
  1846. -------
  1847. Series[bool]
  1848. Series indicating whether each value has occurred in the
  1849. preceding values.
  1850. See Also
  1851. --------
  1852. Index.duplicated : Equivalent method on pandas.Index.
  1853. DataFrame.duplicated : Equivalent method on pandas.DataFrame.
  1854. Series.drop_duplicates : Remove duplicate values from Series.
  1855. Examples
  1856. --------
  1857. By default, for each set of duplicated values, the first occurrence is
  1858. set on False and all others on True:
  1859. >>> animals = pd.Series(['lama', 'cow', 'lama', 'beetle', 'lama'])
  1860. >>> animals.duplicated()
  1861. 0 False
  1862. 1 False
  1863. 2 True
  1864. 3 False
  1865. 4 True
  1866. dtype: bool
  1867. which is equivalent to
  1868. >>> animals.duplicated(keep='first')
  1869. 0 False
  1870. 1 False
  1871. 2 True
  1872. 3 False
  1873. 4 True
  1874. dtype: bool
  1875. By using 'last', the last occurrence of each set of duplicated values
  1876. is set on False and all others on True:
  1877. >>> animals.duplicated(keep='last')
  1878. 0 True
  1879. 1 False
  1880. 2 True
  1881. 3 False
  1882. 4 False
  1883. dtype: bool
  1884. By setting keep on ``False``, all duplicates are True:
  1885. >>> animals.duplicated(keep=False)
  1886. 0 True
  1887. 1 False
  1888. 2 True
  1889. 3 False
  1890. 4 True
  1891. dtype: bool
  1892. """
  1893. res = self._duplicated(keep=keep)
  1894. result = self._constructor(res, index=self.index)
  1895. return result.__finalize__(self, method="duplicated")
  1896. def idxmin(self, axis=0, skipna=True, *args, **kwargs):
  1897. """
  1898. Return the row label of the minimum value.
  1899. If multiple values equal the minimum, the first row label with that
  1900. value is returned.
  1901. Parameters
  1902. ----------
  1903. axis : int, default 0
  1904. For compatibility with DataFrame.idxmin. Redundant for application
  1905. on Series.
  1906. skipna : bool, default True
  1907. Exclude NA/null values. If the entire Series is NA, the result
  1908. will be NA.
  1909. *args, **kwargs
  1910. Additional arguments and keywords have no effect but might be
  1911. accepted for compatibility with NumPy.
  1912. Returns
  1913. -------
  1914. Index
  1915. Label of the minimum value.
  1916. Raises
  1917. ------
  1918. ValueError
  1919. If the Series is empty.
  1920. See Also
  1921. --------
  1922. numpy.argmin : Return indices of the minimum values
  1923. along the given axis.
  1924. DataFrame.idxmin : Return index of first occurrence of minimum
  1925. over requested axis.
  1926. Series.idxmax : Return index *label* of the first occurrence
  1927. of maximum of values.
  1928. Notes
  1929. -----
  1930. This method is the Series version of ``ndarray.argmin``. This method
  1931. returns the label of the minimum, while ``ndarray.argmin`` returns
  1932. the position. To get the position, use ``series.values.argmin()``.
  1933. Examples
  1934. --------
  1935. >>> s = pd.Series(data=[1, None, 4, 1],
  1936. ... index=['A', 'B', 'C', 'D'])
  1937. >>> s
  1938. A 1.0
  1939. B NaN
  1940. C 4.0
  1941. D 1.0
  1942. dtype: float64
  1943. >>> s.idxmin()
  1944. 'A'
  1945. If `skipna` is False and there is an NA value in the data,
  1946. the function returns ``nan``.
  1947. >>> s.idxmin(skipna=False)
  1948. nan
  1949. """
  1950. i = self.argmin(axis, skipna, *args, **kwargs)
  1951. if i == -1:
  1952. return np.nan
  1953. return self.index[i]
  1954. def idxmax(self, axis=0, skipna=True, *args, **kwargs):
  1955. """
  1956. Return the row label of the maximum value.
  1957. If multiple values equal the maximum, the first row label with that
  1958. value is returned.
  1959. Parameters
  1960. ----------
  1961. axis : int, default 0
  1962. For compatibility with DataFrame.idxmax. Redundant for application
  1963. on Series.
  1964. skipna : bool, default True
  1965. Exclude NA/null values. If the entire Series is NA, the result
  1966. will be NA.
  1967. *args, **kwargs
  1968. Additional arguments and keywords have no effect but might be
  1969. accepted for compatibility with NumPy.
  1970. Returns
  1971. -------
  1972. Index
  1973. Label of the maximum value.
  1974. Raises
  1975. ------
  1976. ValueError
  1977. If the Series is empty.
  1978. See Also
  1979. --------
  1980. numpy.argmax : Return indices of the maximum values
  1981. along the given axis.
  1982. DataFrame.idxmax : Return index of first occurrence of maximum
  1983. over requested axis.
  1984. Series.idxmin : Return index *label* of the first occurrence
  1985. of minimum of values.
  1986. Notes
  1987. -----
  1988. This method is the Series version of ``ndarray.argmax``. This method
  1989. returns the label of the maximum, while ``ndarray.argmax`` returns
  1990. the position. To get the position, use ``series.values.argmax()``.
  1991. Examples
  1992. --------
  1993. >>> s = pd.Series(data=[1, None, 4, 3, 4],
  1994. ... index=['A', 'B', 'C', 'D', 'E'])
  1995. >>> s
  1996. A 1.0
  1997. B NaN
  1998. C 4.0
  1999. D 3.0
  2000. E 4.0
  2001. dtype: float64
  2002. >>> s.idxmax()
  2003. 'C'
  2004. If `skipna` is False and there is an NA value in the data,
  2005. the function returns ``nan``.
  2006. >>> s.idxmax(skipna=False)
  2007. nan
  2008. """
  2009. i = self.argmax(axis, skipna, *args, **kwargs)
  2010. if i == -1:
  2011. return np.nan
  2012. return self.index[i]
  2013. def round(self, decimals=0, *args, **kwargs) -> Series:
  2014. """
  2015. Round each value in a Series to the given number of decimals.
  2016. Parameters
  2017. ----------
  2018. decimals : int, default 0
  2019. Number of decimal places to round to. If decimals is negative,
  2020. it specifies the number of positions to the left of the decimal point.
  2021. *args, **kwargs
  2022. Additional arguments and keywords have no effect but might be
  2023. accepted for compatibility with NumPy.
  2024. Returns
  2025. -------
  2026. Series
  2027. Rounded values of the Series.
  2028. See Also
  2029. --------
  2030. numpy.around : Round values of an np.array.
  2031. DataFrame.round : Round values of a DataFrame.
  2032. Examples
  2033. --------
  2034. >>> s = pd.Series([0.1, 1.3, 2.7])
  2035. >>> s.round()
  2036. 0 0.0
  2037. 1 1.0
  2038. 2 3.0
  2039. dtype: float64
  2040. """
  2041. nv.validate_round(args, kwargs)
  2042. result = self._values.round(decimals)
  2043. result = self._constructor(result, index=self.index).__finalize__(
  2044. self, method="round"
  2045. )
  2046. return result
  2047. def quantile(self, q=0.5, interpolation="linear"):
  2048. """
  2049. Return value at the given quantile.
  2050. Parameters
  2051. ----------
  2052. q : float or array-like, default 0.5 (50% quantile)
  2053. The quantile(s) to compute, which can lie in range: 0 <= q <= 1.
  2054. interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'}
  2055. This optional parameter specifies the interpolation method to use,
  2056. when the desired quantile lies between two data points `i` and `j`:
  2057. * linear: `i + (j - i) * fraction`, where `fraction` is the
  2058. fractional part of the index surrounded by `i` and `j`.
  2059. * lower: `i`.
  2060. * higher: `j`.
  2061. * nearest: `i` or `j` whichever is nearest.
  2062. * midpoint: (`i` + `j`) / 2.
  2063. Returns
  2064. -------
  2065. float or Series
  2066. If ``q`` is an array, a Series will be returned where the
  2067. index is ``q`` and the values are the quantiles, otherwise
  2068. a float will be returned.
  2069. See Also
  2070. --------
  2071. core.window.Rolling.quantile : Calculate the rolling quantile.
  2072. numpy.percentile : Returns the q-th percentile(s) of the array elements.
  2073. Examples
  2074. --------
  2075. >>> s = pd.Series([1, 2, 3, 4])
  2076. >>> s.quantile(.5)
  2077. 2.5
  2078. >>> s.quantile([.25, .5, .75])
  2079. 0.25 1.75
  2080. 0.50 2.50
  2081. 0.75 3.25
  2082. dtype: float64
  2083. """
  2084. validate_percentile(q)
  2085. # We dispatch to DataFrame so that core.internals only has to worry
  2086. # about 2D cases.
  2087. df = self.to_frame()
  2088. result = df.quantile(q=q, interpolation=interpolation, numeric_only=False)
  2089. if result.ndim == 2:
  2090. result = result.iloc[:, 0]
  2091. if is_list_like(q):
  2092. result.name = self.name
  2093. return self._constructor(result, index=Float64Index(q), name=self.name)
  2094. else:
  2095. # scalar
  2096. return result.iloc[0]
  2097. def corr(self, other, method="pearson", min_periods=None) -> float:
  2098. """
  2099. Compute correlation with `other` Series, excluding missing values.
  2100. Parameters
  2101. ----------
  2102. other : Series
  2103. Series with which to compute the correlation.
  2104. method : {'pearson', 'kendall', 'spearman'} or callable
  2105. Method used to compute correlation:
  2106. - pearson : Standard correlation coefficient
  2107. - kendall : Kendall Tau correlation coefficient
  2108. - spearman : Spearman rank correlation
  2109. - callable: Callable with input two 1d ndarrays and returning a float.
  2110. .. warning::
  2111. Note that the returned matrix from corr will have 1 along the
  2112. diagonals and will be symmetric regardless of the callable's
  2113. behavior.
  2114. min_periods : int, optional
  2115. Minimum number of observations needed to have a valid result.
  2116. Returns
  2117. -------
  2118. float
  2119. Correlation with other.
  2120. See Also
  2121. --------
  2122. DataFrame.corr : Compute pairwise correlation between columns.
  2123. DataFrame.corrwith : Compute pairwise correlation with another
  2124. DataFrame or Series.
  2125. Examples
  2126. --------
  2127. >>> def histogram_intersection(a, b):
  2128. ... v = np.minimum(a, b).sum().round(decimals=1)
  2129. ... return v
  2130. >>> s1 = pd.Series([.2, .0, .6, .2])
  2131. >>> s2 = pd.Series([.3, .6, .0, .1])
  2132. >>> s1.corr(s2, method=histogram_intersection)
  2133. 0.3
  2134. """
  2135. this, other = self.align(other, join="inner", copy=False)
  2136. if len(this) == 0:
  2137. return np.nan
  2138. if method in ["pearson", "spearman", "kendall"] or callable(method):
  2139. return nanops.nancorr(
  2140. this.values, other.values, method=method, min_periods=min_periods
  2141. )
  2142. raise ValueError(
  2143. "method must be either 'pearson', "
  2144. "'spearman', 'kendall', or a callable, "
  2145. f"'{method}' was supplied"
  2146. )
  2147. def cov(
  2148. self,
  2149. other: Series,
  2150. min_periods: int | None = None,
  2151. ddof: int | None = 1,
  2152. ) -> float:
  2153. """
  2154. Compute covariance with Series, excluding missing values.
  2155. Parameters
  2156. ----------
  2157. other : Series
  2158. Series with which to compute the covariance.
  2159. min_periods : int, optional
  2160. Minimum number of observations needed to have a valid result.
  2161. ddof : int, default 1
  2162. Delta degrees of freedom. The divisor used in calculations
  2163. is ``N - ddof``, where ``N`` represents the number of elements.
  2164. .. versionadded:: 1.1.0
  2165. Returns
  2166. -------
  2167. float
  2168. Covariance between Series and other normalized by N-1
  2169. (unbiased estimator).
  2170. See Also
  2171. --------
  2172. DataFrame.cov : Compute pairwise covariance of columns.
  2173. Examples
  2174. --------
  2175. >>> s1 = pd.Series([0.90010907, 0.13484424, 0.62036035])
  2176. >>> s2 = pd.Series([0.12528585, 0.26962463, 0.51111198])
  2177. >>> s1.cov(s2)
  2178. -0.01685762652715874
  2179. """
  2180. this, other = self.align(other, join="inner", copy=False)
  2181. if len(this) == 0:
  2182. return np.nan
  2183. return nanops.nancov(
  2184. this.values, other.values, min_periods=min_periods, ddof=ddof
  2185. )
  2186. @doc(
  2187. klass="Series",
  2188. extra_params="",
  2189. other_klass="DataFrame",
  2190. examples=dedent(
  2191. """
  2192. Difference with previous row
  2193. >>> s = pd.Series([1, 1, 2, 3, 5, 8])
  2194. >>> s.diff()
  2195. 0 NaN
  2196. 1 0.0
  2197. 2 1.0
  2198. 3 1.0
  2199. 4 2.0
  2200. 5 3.0
  2201. dtype: float64
  2202. Difference with 3rd previous row
  2203. >>> s.diff(periods=3)
  2204. 0 NaN
  2205. 1 NaN
  2206. 2 NaN
  2207. 3 2.0
  2208. 4 4.0
  2209. 5 6.0
  2210. dtype: float64
  2211. Difference with following row
  2212. >>> s.diff(periods=-1)
  2213. 0 0.0
  2214. 1 -1.0
  2215. 2 -1.0
  2216. 3 -2.0
  2217. 4 -3.0
  2218. 5 NaN
  2219. dtype: float64
  2220. Overflow in input dtype
  2221. >>> s = pd.Series([1, 0], dtype=np.uint8)
  2222. >>> s.diff()
  2223. 0 NaN
  2224. 1 255.0
  2225. dtype: float64"""
  2226. ),
  2227. )
  2228. def diff(self, periods: int = 1) -> Series:
  2229. """
  2230. First discrete difference of element.
  2231. Calculates the difference of a {klass} element compared with another
  2232. element in the {klass} (default is element in previous row).
  2233. Parameters
  2234. ----------
  2235. periods : int, default 1
  2236. Periods to shift for calculating difference, accepts negative
  2237. values.
  2238. {extra_params}
  2239. Returns
  2240. -------
  2241. {klass}
  2242. First differences of the Series.
  2243. See Also
  2244. --------
  2245. {klass}.pct_change: Percent change over given number of periods.
  2246. {klass}.shift: Shift index by desired number of periods with an
  2247. optional time freq.
  2248. {other_klass}.diff: First discrete difference of object.
  2249. Notes
  2250. -----
  2251. For boolean dtypes, this uses :meth:`operator.xor` rather than
  2252. :meth:`operator.sub`.
  2253. The result is calculated according to current dtype in {klass},
  2254. however dtype of the result is always float64.
  2255. Examples
  2256. --------
  2257. {examples}
  2258. """
  2259. result = algorithms.diff(self._values, periods)
  2260. return self._constructor(result, index=self.index).__finalize__(
  2261. self, method="diff"
  2262. )
  2263. def autocorr(self, lag=1) -> float:
  2264. """
  2265. Compute the lag-N autocorrelation.
  2266. This method computes the Pearson correlation between
  2267. the Series and its shifted self.
  2268. Parameters
  2269. ----------
  2270. lag : int, default 1
  2271. Number of lags to apply before performing autocorrelation.
  2272. Returns
  2273. -------
  2274. float
  2275. The Pearson correlation between self and self.shift(lag).
  2276. See Also
  2277. --------
  2278. Series.corr : Compute the correlation between two Series.
  2279. Series.shift : Shift index by desired number of periods.
  2280. DataFrame.corr : Compute pairwise correlation of columns.
  2281. DataFrame.corrwith : Compute pairwise correlation between rows or
  2282. columns of two DataFrame objects.
  2283. Notes
  2284. -----
  2285. If the Pearson correlation is not well defined return 'NaN'.
  2286. Examples
  2287. --------
  2288. >>> s = pd.Series([0.25, 0.5, 0.2, -0.05])
  2289. >>> s.autocorr() # doctest: +ELLIPSIS
  2290. 0.10355...
  2291. >>> s.autocorr(lag=2) # doctest: +ELLIPSIS
  2292. -0.99999...
  2293. If the Pearson correlation is not well defined, then 'NaN' is returned.
  2294. >>> s = pd.Series([1, 0, 0, 0])
  2295. >>> s.autocorr()
  2296. nan
  2297. """
  2298. return self.corr(self.shift(lag))
  2299. def dot(self, other):
  2300. """
  2301. Compute the dot product between the Series and the columns of other.
  2302. This method computes the dot product between the Series and another
  2303. one, or the Series and each columns of a DataFrame, or the Series and
  2304. each columns of an array.
  2305. It can also be called using `self @ other` in Python >= 3.5.
  2306. Parameters
  2307. ----------
  2308. other : Series, DataFrame or array-like
  2309. The other object to compute the dot product with its columns.
  2310. Returns
  2311. -------
  2312. scalar, Series or numpy.ndarray
  2313. Return the dot product of the Series and other if other is a
  2314. Series, the Series of the dot product of Series and each rows of
  2315. other if other is a DataFrame or a numpy.ndarray between the Series
  2316. and each columns of the numpy array.
  2317. See Also
  2318. --------
  2319. DataFrame.dot: Compute the matrix product with the DataFrame.
  2320. Series.mul: Multiplication of series and other, element-wise.
  2321. Notes
  2322. -----
  2323. The Series and other has to share the same index if other is a Series
  2324. or a DataFrame.
  2325. Examples
  2326. --------
  2327. >>> s = pd.Series([0, 1, 2, 3])
  2328. >>> other = pd.Series([-1, 2, -3, 4])
  2329. >>> s.dot(other)
  2330. 8
  2331. >>> s @ other
  2332. 8
  2333. >>> df = pd.DataFrame([[0, 1], [-2, 3], [4, -5], [6, 7]])
  2334. >>> s.dot(df)
  2335. 0 24
  2336. 1 14
  2337. dtype: int64
  2338. >>> arr = np.array([[0, 1], [-2, 3], [4, -5], [6, 7]])
  2339. >>> s.dot(arr)
  2340. array([24, 14])
  2341. """
  2342. if isinstance(other, (Series, ABCDataFrame)):
  2343. common = self.index.union(other.index)
  2344. if len(common) > len(self.index) or len(common) > len(other.index):
  2345. raise ValueError("matrices are not aligned")
  2346. left = self.reindex(index=common, copy=False)
  2347. right = other.reindex(index=common, copy=False)
  2348. lvals = left.values
  2349. rvals = right.values
  2350. else:
  2351. lvals = self.values
  2352. rvals = np.asarray(other)
  2353. if lvals.shape[0] != rvals.shape[0]:
  2354. raise Exception(
  2355. f"Dot product shape mismatch, {lvals.shape} vs {rvals.shape}"
  2356. )
  2357. if isinstance(other, ABCDataFrame):
  2358. return self._constructor(
  2359. np.dot(lvals, rvals), index=other.columns
  2360. ).__finalize__(self, method="dot")
  2361. elif isinstance(other, Series):
  2362. return np.dot(lvals, rvals)
  2363. elif isinstance(rvals, np.ndarray):
  2364. return np.dot(lvals, rvals)
  2365. else: # pragma: no cover
  2366. raise TypeError(f"unsupported type: {type(other)}")
  2367. def __matmul__(self, other):
  2368. """
  2369. Matrix multiplication using binary `@` operator in Python>=3.5.
  2370. """
  2371. return self.dot(other)
  2372. def __rmatmul__(self, other):
  2373. """
  2374. Matrix multiplication using binary `@` operator in Python>=3.5.
  2375. """
  2376. return self.dot(np.transpose(other))
  2377. @doc(base.IndexOpsMixin.searchsorted, klass="Series")
  2378. # Signature of "searchsorted" incompatible with supertype "IndexOpsMixin"
  2379. def searchsorted( # type: ignore[override]
  2380. self,
  2381. value: NumpyValueArrayLike | ExtensionArray,
  2382. side: Literal["left", "right"] = "left",
  2383. sorter: NumpySorter = None,
  2384. ) -> npt.NDArray[np.intp] | np.intp:
  2385. return base.IndexOpsMixin.searchsorted(self, value, side=side, sorter=sorter)
  2386. # -------------------------------------------------------------------
  2387. # Combination
  2388. def append(
  2389. self, to_append, ignore_index: bool = False, verify_integrity: bool = False
  2390. ):
  2391. """
  2392. Concatenate two or more Series.
  2393. Parameters
  2394. ----------
  2395. to_append : Series or list/tuple of Series
  2396. Series to append with self.
  2397. ignore_index : bool, default False
  2398. If True, the resulting axis will be labeled 0, 1, …, n - 1.
  2399. verify_integrity : bool, default False
  2400. If True, raise Exception on creating index with duplicates.
  2401. Returns
  2402. -------
  2403. Series
  2404. Concatenated Series.
  2405. See Also
  2406. --------
  2407. concat : General function to concatenate DataFrame or Series objects.
  2408. Notes
  2409. -----
  2410. Iteratively appending to a Series can be more computationally intensive
  2411. than a single concatenate. A better solution is to append values to a
  2412. list and then concatenate the list with the original Series all at
  2413. once.
  2414. Examples
  2415. --------
  2416. >>> s1 = pd.Series([1, 2, 3])
  2417. >>> s2 = pd.Series([4, 5, 6])
  2418. >>> s3 = pd.Series([4, 5, 6], index=[3, 4, 5])
  2419. >>> s1.append(s2)
  2420. 0 1
  2421. 1 2
  2422. 2 3
  2423. 0 4
  2424. 1 5
  2425. 2 6
  2426. dtype: int64
  2427. >>> s1.append(s3)
  2428. 0 1
  2429. 1 2
  2430. 2 3
  2431. 3 4
  2432. 4 5
  2433. 5 6
  2434. dtype: int64
  2435. With `ignore_index` set to True:
  2436. >>> s1.append(s2, ignore_index=True)
  2437. 0 1
  2438. 1 2
  2439. 2 3
  2440. 3 4
  2441. 4 5
  2442. 5 6
  2443. dtype: int64
  2444. With `verify_integrity` set to True:
  2445. >>> s1.append(s2, verify_integrity=True)
  2446. Traceback (most recent call last):
  2447. ...
  2448. ValueError: Indexes have overlapping values: [0, 1, 2]
  2449. """
  2450. from pandas.core.reshape.concat import concat
  2451. if isinstance(to_append, (list, tuple)):
  2452. to_concat = [self]
  2453. to_concat.extend(to_append)
  2454. else:
  2455. to_concat = [self, to_append]
  2456. if any(isinstance(x, (ABCDataFrame,)) for x in to_concat[1:]):
  2457. msg = "to_append should be a Series or list/tuple of Series, got DataFrame"
  2458. raise TypeError(msg)
  2459. return concat(
  2460. to_concat, ignore_index=ignore_index, verify_integrity=verify_integrity
  2461. )
  2462. def _binop(self, other: Series, func, level=None, fill_value=None):
  2463. """
  2464. Perform generic binary operation with optional fill value.
  2465. Parameters
  2466. ----------
  2467. other : Series
  2468. func : binary operator
  2469. fill_value : float or object
  2470. Value to substitute for NA/null values. If both Series are NA in a
  2471. location, the result will be NA regardless of the passed fill value.
  2472. level : int or level name, default None
  2473. Broadcast across a level, matching Index values on the
  2474. passed MultiIndex level.
  2475. Returns
  2476. -------
  2477. Series
  2478. """
  2479. if not isinstance(other, Series):
  2480. raise AssertionError("Other operand must be Series")
  2481. this = self
  2482. if not self.index.equals(other.index):
  2483. this, other = self.align(other, level=level, join="outer", copy=False)
  2484. this_vals, other_vals = ops.fill_binop(this._values, other._values, fill_value)
  2485. with np.errstate(all="ignore"):
  2486. result = func(this_vals, other_vals)
  2487. name = ops.get_op_result_name(self, other)
  2488. return this._construct_result(result, name)
  2489. def _construct_result(
  2490. self, result: ArrayLike | tuple[ArrayLike, ArrayLike], name: Hashable
  2491. ) -> Series | tuple[Series, Series]:
  2492. """
  2493. Construct an appropriately-labelled Series from the result of an op.
  2494. Parameters
  2495. ----------
  2496. result : ndarray or ExtensionArray
  2497. name : Label
  2498. Returns
  2499. -------
  2500. Series
  2501. In the case of __divmod__ or __rdivmod__, a 2-tuple of Series.
  2502. """
  2503. if isinstance(result, tuple):
  2504. # produced by divmod or rdivmod
  2505. res1 = self._construct_result(result[0], name=name)
  2506. res2 = self._construct_result(result[1], name=name)
  2507. # GH#33427 assertions to keep mypy happy
  2508. assert isinstance(res1, Series)
  2509. assert isinstance(res2, Series)
  2510. return (res1, res2)
  2511. # We do not pass dtype to ensure that the Series constructor
  2512. # does inference in the case where `result` has object-dtype.
  2513. out = self._constructor(result, index=self.index)
  2514. out = out.__finalize__(self)
  2515. # Set the result's name after __finalize__ is called because __finalize__
  2516. # would set it back to self.name
  2517. out.name = name
  2518. return out
  2519. @doc(
  2520. generic._shared_docs["compare"],
  2521. """
  2522. Returns
  2523. -------
  2524. Series or DataFrame
  2525. If axis is 0 or 'index' the result will be a Series.
  2526. The resulting index will be a MultiIndex with 'self' and 'other'
  2527. stacked alternately at the inner level.
  2528. If axis is 1 or 'columns' the result will be a DataFrame.
  2529. It will have two columns namely 'self' and 'other'.
  2530. See Also
  2531. --------
  2532. DataFrame.compare : Compare with another DataFrame and show differences.
  2533. Notes
  2534. -----
  2535. Matching NaNs will not appear as a difference.
  2536. Examples
  2537. --------
  2538. >>> s1 = pd.Series(["a", "b", "c", "d", "e"])
  2539. >>> s2 = pd.Series(["a", "a", "c", "b", "e"])
  2540. Align the differences on columns
  2541. >>> s1.compare(s2)
  2542. self other
  2543. 1 b a
  2544. 3 d b
  2545. Stack the differences on indices
  2546. >>> s1.compare(s2, align_axis=0)
  2547. 1 self b
  2548. other a
  2549. 3 self d
  2550. other b
  2551. dtype: object
  2552. Keep all original rows
  2553. >>> s1.compare(s2, keep_shape=True)
  2554. self other
  2555. 0 NaN NaN
  2556. 1 b a
  2557. 2 NaN NaN
  2558. 3 d b
  2559. 4 NaN NaN
  2560. Keep all original rows and also all original values
  2561. >>> s1.compare(s2, keep_shape=True, keep_equal=True)
  2562. self other
  2563. 0 a a
  2564. 1 b a
  2565. 2 c c
  2566. 3 d b
  2567. 4 e e
  2568. """,
  2569. klass=_shared_doc_kwargs["klass"],
  2570. )
  2571. def compare(
  2572. self,
  2573. other: Series,
  2574. align_axis: Axis = 1,
  2575. keep_shape: bool = False,
  2576. keep_equal: bool = False,
  2577. ) -> DataFrame | Series:
  2578. return super().compare(
  2579. other=other,
  2580. align_axis=align_axis,
  2581. keep_shape=keep_shape,
  2582. keep_equal=keep_equal,
  2583. )
  2584. def combine(self, other, func, fill_value=None) -> Series:
  2585. """
  2586. Combine the Series with a Series or scalar according to `func`.
  2587. Combine the Series and `other` using `func` to perform elementwise
  2588. selection for combined Series.
  2589. `fill_value` is assumed when value is missing at some index
  2590. from one of the two objects being combined.
  2591. Parameters
  2592. ----------
  2593. other : Series or scalar
  2594. The value(s) to be combined with the `Series`.
  2595. func : function
  2596. Function that takes two scalars as inputs and returns an element.
  2597. fill_value : scalar, optional
  2598. The value to assume when an index is missing from
  2599. one Series or the other. The default specifies to use the
  2600. appropriate NaN value for the underlying dtype of the Series.
  2601. Returns
  2602. -------
  2603. Series
  2604. The result of combining the Series with the other object.
  2605. See Also
  2606. --------
  2607. Series.combine_first : Combine Series values, choosing the calling
  2608. Series' values first.
  2609. Examples
  2610. --------
  2611. Consider 2 Datasets ``s1`` and ``s2`` containing
  2612. highest clocked speeds of different birds.
  2613. >>> s1 = pd.Series({'falcon': 330.0, 'eagle': 160.0})
  2614. >>> s1
  2615. falcon 330.0
  2616. eagle 160.0
  2617. dtype: float64
  2618. >>> s2 = pd.Series({'falcon': 345.0, 'eagle': 200.0, 'duck': 30.0})
  2619. >>> s2
  2620. falcon 345.0
  2621. eagle 200.0
  2622. duck 30.0
  2623. dtype: float64
  2624. Now, to combine the two datasets and view the highest speeds
  2625. of the birds across the two datasets
  2626. >>> s1.combine(s2, max)
  2627. duck NaN
  2628. eagle 200.0
  2629. falcon 345.0
  2630. dtype: float64
  2631. In the previous example, the resulting value for duck is missing,
  2632. because the maximum of a NaN and a float is a NaN.
  2633. So, in the example, we set ``fill_value=0``,
  2634. so the maximum value returned will be the value from some dataset.
  2635. >>> s1.combine(s2, max, fill_value=0)
  2636. duck 30.0
  2637. eagle 200.0
  2638. falcon 345.0
  2639. dtype: float64
  2640. """
  2641. if fill_value is None:
  2642. fill_value = na_value_for_dtype(self.dtype, compat=False)
  2643. if isinstance(other, Series):
  2644. # If other is a Series, result is based on union of Series,
  2645. # so do this element by element
  2646. new_index = self.index.union(other.index)
  2647. new_name = ops.get_op_result_name(self, other)
  2648. new_values = np.empty(len(new_index), dtype=object)
  2649. for i, idx in enumerate(new_index):
  2650. lv = self.get(idx, fill_value)
  2651. rv = other.get(idx, fill_value)
  2652. with np.errstate(all="ignore"):
  2653. new_values[i] = func(lv, rv)
  2654. else:
  2655. # Assume that other is a scalar, so apply the function for
  2656. # each element in the Series
  2657. new_index = self.index
  2658. new_values = np.empty(len(new_index), dtype=object)
  2659. with np.errstate(all="ignore"):
  2660. new_values[:] = [func(lv, other) for lv in self._values]
  2661. new_name = self.name
  2662. # try_float=False is to match agg_series
  2663. npvalues = lib.maybe_convert_objects(new_values, try_float=False)
  2664. res_values = maybe_cast_pointwise_result(npvalues, self.dtype, same_dtype=False)
  2665. return self._constructor(res_values, index=new_index, name=new_name)
  2666. def combine_first(self, other) -> Series:
  2667. """
  2668. Update null elements with value in the same location in 'other'.
  2669. Combine two Series objects by filling null values in one Series with
  2670. non-null values from the other Series. Result index will be the union
  2671. of the two indexes.
  2672. Parameters
  2673. ----------
  2674. other : Series
  2675. The value(s) to be used for filling null values.
  2676. Returns
  2677. -------
  2678. Series
  2679. The result of combining the provided Series with the other object.
  2680. See Also
  2681. --------
  2682. Series.combine : Perform element-wise operation on two Series
  2683. using a given function.
  2684. Examples
  2685. --------
  2686. >>> s1 = pd.Series([1, np.nan])
  2687. >>> s2 = pd.Series([3, 4, 5])
  2688. >>> s1.combine_first(s2)
  2689. 0 1.0
  2690. 1 4.0
  2691. 2 5.0
  2692. dtype: float64
  2693. Null values still persist if the location of that null value
  2694. does not exist in `other`
  2695. >>> s1 = pd.Series({'falcon': np.nan, 'eagle': 160.0})
  2696. >>> s2 = pd.Series({'eagle': 200.0, 'duck': 30.0})
  2697. >>> s1.combine_first(s2)
  2698. duck 30.0
  2699. eagle 160.0
  2700. falcon NaN
  2701. dtype: float64
  2702. """
  2703. new_index = self.index.union(other.index)
  2704. this = self.reindex(new_index, copy=False)
  2705. other = other.reindex(new_index, copy=False)
  2706. if this.dtype.kind == "M" and other.dtype.kind != "M":
  2707. other = to_datetime(other)
  2708. return this.where(notna(this), other)
  2709. def update(self, other) -> None:
  2710. """
  2711. Modify Series in place using values from passed Series.
  2712. Uses non-NA values from passed Series to make updates. Aligns
  2713. on index.
  2714. Parameters
  2715. ----------
  2716. other : Series, or object coercible into Series
  2717. Examples
  2718. --------
  2719. >>> s = pd.Series([1, 2, 3])
  2720. >>> s.update(pd.Series([4, 5, 6]))
  2721. >>> s
  2722. 0 4
  2723. 1 5
  2724. 2 6
  2725. dtype: int64
  2726. >>> s = pd.Series(['a', 'b', 'c'])
  2727. >>> s.update(pd.Series(['d', 'e'], index=[0, 2]))
  2728. >>> s
  2729. 0 d
  2730. 1 b
  2731. 2 e
  2732. dtype: object
  2733. >>> s = pd.Series([1, 2, 3])
  2734. >>> s.update(pd.Series([4, 5, 6, 7, 8]))
  2735. >>> s
  2736. 0 4
  2737. 1 5
  2738. 2 6
  2739. dtype: int64
  2740. If ``other`` contains NaNs the corresponding values are not updated
  2741. in the original Series.
  2742. >>> s = pd.Series([1, 2, 3])
  2743. >>> s.update(pd.Series([4, np.nan, 6]))
  2744. >>> s
  2745. 0 4
  2746. 1 2
  2747. 2 6
  2748. dtype: int64
  2749. ``other`` can also be a non-Series object type
  2750. that is coercible into a Series
  2751. >>> s = pd.Series([1, 2, 3])
  2752. >>> s.update([4, np.nan, 6])
  2753. >>> s
  2754. 0 4
  2755. 1 2
  2756. 2 6
  2757. dtype: int64
  2758. >>> s = pd.Series([1, 2, 3])
  2759. >>> s.update({1: 9})
  2760. >>> s
  2761. 0 1
  2762. 1 9
  2763. 2 3
  2764. dtype: int64
  2765. """
  2766. if not isinstance(other, Series):
  2767. other = Series(other)
  2768. other = other.reindex_like(self)
  2769. mask = notna(other)
  2770. self._mgr = self._mgr.putmask(mask=mask, new=other)
  2771. self._maybe_update_cacher()
  2772. # ----------------------------------------------------------------------
  2773. # Reindexing, sorting
  2774. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
  2775. def sort_values(
  2776. self,
  2777. axis=0,
  2778. ascending: bool | int | Sequence[bool | int] = True,
  2779. inplace: bool = False,
  2780. kind: str = "quicksort",
  2781. na_position: str = "last",
  2782. ignore_index: bool = False,
  2783. key: ValueKeyFunc = None,
  2784. ):
  2785. """
  2786. Sort by the values.
  2787. Sort a Series in ascending or descending order by some
  2788. criterion.
  2789. Parameters
  2790. ----------
  2791. axis : {0 or 'index'}, default 0
  2792. Axis to direct sorting. The value 'index' is accepted for
  2793. compatibility with DataFrame.sort_values.
  2794. ascending : bool or list of bools, default True
  2795. If True, sort values in ascending order, otherwise descending.
  2796. inplace : bool, default False
  2797. If True, perform operation in-place.
  2798. kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, default 'quicksort'
  2799. Choice of sorting algorithm. See also :func:`numpy.sort` for more
  2800. information. 'mergesort' and 'stable' are the only stable algorithms.
  2801. na_position : {'first' or 'last'}, default 'last'
  2802. Argument 'first' puts NaNs at the beginning, 'last' puts NaNs at
  2803. the end.
  2804. ignore_index : bool, default False
  2805. If True, the resulting axis will be labeled 0, 1, …, n - 1.
  2806. .. versionadded:: 1.0.0
  2807. key : callable, optional
  2808. If not None, apply the key function to the series values
  2809. before sorting. This is similar to the `key` argument in the
  2810. builtin :meth:`sorted` function, with the notable difference that
  2811. this `key` function should be *vectorized*. It should expect a
  2812. ``Series`` and return an array-like.
  2813. .. versionadded:: 1.1.0
  2814. Returns
  2815. -------
  2816. Series or None
  2817. Series ordered by values or None if ``inplace=True``.
  2818. See Also
  2819. --------
  2820. Series.sort_index : Sort by the Series indices.
  2821. DataFrame.sort_values : Sort DataFrame by the values along either axis.
  2822. DataFrame.sort_index : Sort DataFrame by indices.
  2823. Examples
  2824. --------
  2825. >>> s = pd.Series([np.nan, 1, 3, 10, 5])
  2826. >>> s
  2827. 0 NaN
  2828. 1 1.0
  2829. 2 3.0
  2830. 3 10.0
  2831. 4 5.0
  2832. dtype: float64
  2833. Sort values ascending order (default behaviour)
  2834. >>> s.sort_values(ascending=True)
  2835. 1 1.0
  2836. 2 3.0
  2837. 4 5.0
  2838. 3 10.0
  2839. 0 NaN
  2840. dtype: float64
  2841. Sort values descending order
  2842. >>> s.sort_values(ascending=False)
  2843. 3 10.0
  2844. 4 5.0
  2845. 2 3.0
  2846. 1 1.0
  2847. 0 NaN
  2848. dtype: float64
  2849. Sort values inplace
  2850. >>> s.sort_values(ascending=False, inplace=True)
  2851. >>> s
  2852. 3 10.0
  2853. 4 5.0
  2854. 2 3.0
  2855. 1 1.0
  2856. 0 NaN
  2857. dtype: float64
  2858. Sort values putting NAs first
  2859. >>> s.sort_values(na_position='first')
  2860. 0 NaN
  2861. 1 1.0
  2862. 2 3.0
  2863. 4 5.0
  2864. 3 10.0
  2865. dtype: float64
  2866. Sort a series of strings
  2867. >>> s = pd.Series(['z', 'b', 'd', 'a', 'c'])
  2868. >>> s
  2869. 0 z
  2870. 1 b
  2871. 2 d
  2872. 3 a
  2873. 4 c
  2874. dtype: object
  2875. >>> s.sort_values()
  2876. 3 a
  2877. 1 b
  2878. 4 c
  2879. 2 d
  2880. 0 z
  2881. dtype: object
  2882. Sort using a key function. Your `key` function will be
  2883. given the ``Series`` of values and should return an array-like.
  2884. >>> s = pd.Series(['a', 'B', 'c', 'D', 'e'])
  2885. >>> s.sort_values()
  2886. 1 B
  2887. 3 D
  2888. 0 a
  2889. 2 c
  2890. 4 e
  2891. dtype: object
  2892. >>> s.sort_values(key=lambda x: x.str.lower())
  2893. 0 a
  2894. 1 B
  2895. 2 c
  2896. 3 D
  2897. 4 e
  2898. dtype: object
  2899. NumPy ufuncs work well here. For example, we can
  2900. sort by the ``sin`` of the value
  2901. >>> s = pd.Series([-4, -2, 0, 2, 4])
  2902. >>> s.sort_values(key=np.sin)
  2903. 1 -2
  2904. 4 4
  2905. 2 0
  2906. 0 -4
  2907. 3 2
  2908. dtype: int64
  2909. More complicated user-defined functions can be used,
  2910. as long as they expect a Series and return an array-like
  2911. >>> s.sort_values(key=lambda x: (np.tan(x.cumsum())))
  2912. 0 -4
  2913. 3 2
  2914. 4 4
  2915. 1 -2
  2916. 2 0
  2917. dtype: int64
  2918. """
  2919. inplace = validate_bool_kwarg(inplace, "inplace")
  2920. # Validate the axis parameter
  2921. self._get_axis_number(axis)
  2922. # GH 5856/5853
  2923. if inplace and self._is_cached:
  2924. raise ValueError(
  2925. "This Series is a view of some other array, to "
  2926. "sort in-place you must create a copy"
  2927. )
  2928. if is_list_like(ascending):
  2929. ascending = cast(Sequence[Union[bool, int]], ascending)
  2930. if len(ascending) != 1:
  2931. raise ValueError(
  2932. f"Length of ascending ({len(ascending)}) must be 1 for Series"
  2933. )
  2934. ascending = ascending[0]
  2935. ascending = validate_ascending(ascending)
  2936. if na_position not in ["first", "last"]:
  2937. raise ValueError(f"invalid na_position: {na_position}")
  2938. # GH 35922. Make sorting stable by leveraging nargsort
  2939. values_to_sort = ensure_key_mapped(self, key)._values if key else self._values
  2940. sorted_index = nargsort(values_to_sort, kind, bool(ascending), na_position)
  2941. result = self._constructor(
  2942. self._values[sorted_index], index=self.index[sorted_index]
  2943. )
  2944. if ignore_index:
  2945. result.index = default_index(len(sorted_index))
  2946. if inplace:
  2947. self._update_inplace(result)
  2948. else:
  2949. return result.__finalize__(self, method="sort_values")
  2950. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
  2951. def sort_index(
  2952. self,
  2953. axis=0,
  2954. level=None,
  2955. ascending: bool | int | Sequence[bool | int] = True,
  2956. inplace: bool = False,
  2957. kind: str = "quicksort",
  2958. na_position: str = "last",
  2959. sort_remaining: bool = True,
  2960. ignore_index: bool = False,
  2961. key: IndexKeyFunc = None,
  2962. ):
  2963. """
  2964. Sort Series by index labels.
  2965. Returns a new Series sorted by label if `inplace` argument is
  2966. ``False``, otherwise updates the original series and returns None.
  2967. Parameters
  2968. ----------
  2969. axis : int, default 0
  2970. Axis to direct sorting. This can only be 0 for Series.
  2971. level : int, optional
  2972. If not None, sort on values in specified index level(s).
  2973. ascending : bool or list-like of bools, default True
  2974. Sort ascending vs. descending. When the index is a MultiIndex the
  2975. sort direction can be controlled for each level individually.
  2976. inplace : bool, default False
  2977. If True, perform operation in-place.
  2978. kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, default 'quicksort'
  2979. Choice of sorting algorithm. See also :func:`numpy.sort` for more
  2980. information. 'mergesort' and 'stable' are the only stable algorithms. For
  2981. DataFrames, this option is only applied when sorting on a single
  2982. column or label.
  2983. na_position : {'first', 'last'}, default 'last'
  2984. If 'first' puts NaNs at the beginning, 'last' puts NaNs at the end.
  2985. Not implemented for MultiIndex.
  2986. sort_remaining : bool, default True
  2987. If True and sorting by level and index is multilevel, sort by other
  2988. levels too (in order) after sorting by specified level.
  2989. ignore_index : bool, default False
  2990. If True, the resulting axis will be labeled 0, 1, …, n - 1.
  2991. .. versionadded:: 1.0.0
  2992. key : callable, optional
  2993. If not None, apply the key function to the index values
  2994. before sorting. This is similar to the `key` argument in the
  2995. builtin :meth:`sorted` function, with the notable difference that
  2996. this `key` function should be *vectorized*. It should expect an
  2997. ``Index`` and return an ``Index`` of the same shape.
  2998. .. versionadded:: 1.1.0
  2999. Returns
  3000. -------
  3001. Series or None
  3002. The original Series sorted by the labels or None if ``inplace=True``.
  3003. See Also
  3004. --------
  3005. DataFrame.sort_index: Sort DataFrame by the index.
  3006. DataFrame.sort_values: Sort DataFrame by the value.
  3007. Series.sort_values : Sort Series by the value.
  3008. Examples
  3009. --------
  3010. >>> s = pd.Series(['a', 'b', 'c', 'd'], index=[3, 2, 1, 4])
  3011. >>> s.sort_index()
  3012. 1 c
  3013. 2 b
  3014. 3 a
  3015. 4 d
  3016. dtype: object
  3017. Sort Descending
  3018. >>> s.sort_index(ascending=False)
  3019. 4 d
  3020. 3 a
  3021. 2 b
  3022. 1 c
  3023. dtype: object
  3024. Sort Inplace
  3025. >>> s.sort_index(inplace=True)
  3026. >>> s
  3027. 1 c
  3028. 2 b
  3029. 3 a
  3030. 4 d
  3031. dtype: object
  3032. By default NaNs are put at the end, but use `na_position` to place
  3033. them at the beginning
  3034. >>> s = pd.Series(['a', 'b', 'c', 'd'], index=[3, 2, 1, np.nan])
  3035. >>> s.sort_index(na_position='first')
  3036. NaN d
  3037. 1.0 c
  3038. 2.0 b
  3039. 3.0 a
  3040. dtype: object
  3041. Specify index level to sort
  3042. >>> arrays = [np.array(['qux', 'qux', 'foo', 'foo',
  3043. ... 'baz', 'baz', 'bar', 'bar']),
  3044. ... np.array(['two', 'one', 'two', 'one',
  3045. ... 'two', 'one', 'two', 'one'])]
  3046. >>> s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8], index=arrays)
  3047. >>> s.sort_index(level=1)
  3048. bar one 8
  3049. baz one 6
  3050. foo one 4
  3051. qux one 2
  3052. bar two 7
  3053. baz two 5
  3054. foo two 3
  3055. qux two 1
  3056. dtype: int64
  3057. Does not sort by remaining levels when sorting by levels
  3058. >>> s.sort_index(level=1, sort_remaining=False)
  3059. qux one 2
  3060. foo one 4
  3061. baz one 6
  3062. bar one 8
  3063. qux two 1
  3064. foo two 3
  3065. baz two 5
  3066. bar two 7
  3067. dtype: int64
  3068. Apply a key function before sorting
  3069. >>> s = pd.Series([1, 2, 3, 4], index=['A', 'b', 'C', 'd'])
  3070. >>> s.sort_index(key=lambda x : x.str.lower())
  3071. A 1
  3072. b 2
  3073. C 3
  3074. d 4
  3075. dtype: int64
  3076. """
  3077. return super().sort_index(
  3078. axis,
  3079. level,
  3080. ascending,
  3081. inplace,
  3082. kind,
  3083. na_position,
  3084. sort_remaining,
  3085. ignore_index,
  3086. key,
  3087. )
  3088. def argsort(self, axis=0, kind="quicksort", order=None) -> Series:
  3089. """
  3090. Return the integer indices that would sort the Series values.
  3091. Override ndarray.argsort. Argsorts the value, omitting NA/null values,
  3092. and places the result in the same locations as the non-NA values.
  3093. Parameters
  3094. ----------
  3095. axis : {0 or "index"}
  3096. Has no effect but is accepted for compatibility with numpy.
  3097. kind : {'mergesort', 'quicksort', 'heapsort', 'stable'}, default 'quicksort'
  3098. Choice of sorting algorithm. See :func:`numpy.sort` for more
  3099. information. 'mergesort' and 'stable' are the only stable algorithms.
  3100. order : None
  3101. Has no effect but is accepted for compatibility with numpy.
  3102. Returns
  3103. -------
  3104. Series[np.intp]
  3105. Positions of values within the sort order with -1 indicating
  3106. nan values.
  3107. See Also
  3108. --------
  3109. numpy.ndarray.argsort : Returns the indices that would sort this array.
  3110. """
  3111. values = self._values
  3112. mask = isna(values)
  3113. if mask.any():
  3114. result = np.full(len(self), -1, dtype=np.intp)
  3115. notmask = ~mask
  3116. result[notmask] = np.argsort(values[notmask], kind=kind)
  3117. else:
  3118. result = np.argsort(values, kind=kind)
  3119. res = self._constructor(result, index=self.index, name=self.name, dtype=np.intp)
  3120. return res.__finalize__(self, method="argsort")
  3121. def nlargest(self, n=5, keep="first") -> Series:
  3122. """
  3123. Return the largest `n` elements.
  3124. Parameters
  3125. ----------
  3126. n : int, default 5
  3127. Return this many descending sorted values.
  3128. keep : {'first', 'last', 'all'}, default 'first'
  3129. When there are duplicate values that cannot all fit in a
  3130. Series of `n` elements:
  3131. - ``first`` : return the first `n` occurrences in order
  3132. of appearance.
  3133. - ``last`` : return the last `n` occurrences in reverse
  3134. order of appearance.
  3135. - ``all`` : keep all occurrences. This can result in a Series of
  3136. size larger than `n`.
  3137. Returns
  3138. -------
  3139. Series
  3140. The `n` largest values in the Series, sorted in decreasing order.
  3141. See Also
  3142. --------
  3143. Series.nsmallest: Get the `n` smallest elements.
  3144. Series.sort_values: Sort Series by values.
  3145. Series.head: Return the first `n` rows.
  3146. Notes
  3147. -----
  3148. Faster than ``.sort_values(ascending=False).head(n)`` for small `n`
  3149. relative to the size of the ``Series`` object.
  3150. Examples
  3151. --------
  3152. >>> countries_population = {"Italy": 59000000, "France": 65000000,
  3153. ... "Malta": 434000, "Maldives": 434000,
  3154. ... "Brunei": 434000, "Iceland": 337000,
  3155. ... "Nauru": 11300, "Tuvalu": 11300,
  3156. ... "Anguilla": 11300, "Montserrat": 5200}
  3157. >>> s = pd.Series(countries_population)
  3158. >>> s
  3159. Italy 59000000
  3160. France 65000000
  3161. Malta 434000
  3162. Maldives 434000
  3163. Brunei 434000
  3164. Iceland 337000
  3165. Nauru 11300
  3166. Tuvalu 11300
  3167. Anguilla 11300
  3168. Montserrat 5200
  3169. dtype: int64
  3170. The `n` largest elements where ``n=5`` by default.
  3171. >>> s.nlargest()
  3172. France 65000000
  3173. Italy 59000000
  3174. Malta 434000
  3175. Maldives 434000
  3176. Brunei 434000
  3177. dtype: int64
  3178. The `n` largest elements where ``n=3``. Default `keep` value is 'first'
  3179. so Malta will be kept.
  3180. >>> s.nlargest(3)
  3181. France 65000000
  3182. Italy 59000000
  3183. Malta 434000
  3184. dtype: int64
  3185. The `n` largest elements where ``n=3`` and keeping the last duplicates.
  3186. Brunei will be kept since it is the last with value 434000 based on
  3187. the index order.
  3188. >>> s.nlargest(3, keep='last')
  3189. France 65000000
  3190. Italy 59000000
  3191. Brunei 434000
  3192. dtype: int64
  3193. The `n` largest elements where ``n=3`` with all duplicates kept. Note
  3194. that the returned Series has five elements due to the three duplicates.
  3195. >>> s.nlargest(3, keep='all')
  3196. France 65000000
  3197. Italy 59000000
  3198. Malta 434000
  3199. Maldives 434000
  3200. Brunei 434000
  3201. dtype: int64
  3202. """
  3203. return algorithms.SelectNSeries(self, n=n, keep=keep).nlargest()
  3204. def nsmallest(self, n: int = 5, keep: str = "first") -> Series:
  3205. """
  3206. Return the smallest `n` elements.
  3207. Parameters
  3208. ----------
  3209. n : int, default 5
  3210. Return this many ascending sorted values.
  3211. keep : {'first', 'last', 'all'}, default 'first'
  3212. When there are duplicate values that cannot all fit in a
  3213. Series of `n` elements:
  3214. - ``first`` : return the first `n` occurrences in order
  3215. of appearance.
  3216. - ``last`` : return the last `n` occurrences in reverse
  3217. order of appearance.
  3218. - ``all`` : keep all occurrences. This can result in a Series of
  3219. size larger than `n`.
  3220. Returns
  3221. -------
  3222. Series
  3223. The `n` smallest values in the Series, sorted in increasing order.
  3224. See Also
  3225. --------
  3226. Series.nlargest: Get the `n` largest elements.
  3227. Series.sort_values: Sort Series by values.
  3228. Series.head: Return the first `n` rows.
  3229. Notes
  3230. -----
  3231. Faster than ``.sort_values().head(n)`` for small `n` relative to
  3232. the size of the ``Series`` object.
  3233. Examples
  3234. --------
  3235. >>> countries_population = {"Italy": 59000000, "France": 65000000,
  3236. ... "Brunei": 434000, "Malta": 434000,
  3237. ... "Maldives": 434000, "Iceland": 337000,
  3238. ... "Nauru": 11300, "Tuvalu": 11300,
  3239. ... "Anguilla": 11300, "Montserrat": 5200}
  3240. >>> s = pd.Series(countries_population)
  3241. >>> s
  3242. Italy 59000000
  3243. France 65000000
  3244. Brunei 434000
  3245. Malta 434000
  3246. Maldives 434000
  3247. Iceland 337000
  3248. Nauru 11300
  3249. Tuvalu 11300
  3250. Anguilla 11300
  3251. Montserrat 5200
  3252. dtype: int64
  3253. The `n` smallest elements where ``n=5`` by default.
  3254. >>> s.nsmallest()
  3255. Montserrat 5200
  3256. Nauru 11300
  3257. Tuvalu 11300
  3258. Anguilla 11300
  3259. Iceland 337000
  3260. dtype: int64
  3261. The `n` smallest elements where ``n=3``. Default `keep` value is
  3262. 'first' so Nauru and Tuvalu will be kept.
  3263. >>> s.nsmallest(3)
  3264. Montserrat 5200
  3265. Nauru 11300
  3266. Tuvalu 11300
  3267. dtype: int64
  3268. The `n` smallest elements where ``n=3`` and keeping the last
  3269. duplicates. Anguilla and Tuvalu will be kept since they are the last
  3270. with value 11300 based on the index order.
  3271. >>> s.nsmallest(3, keep='last')
  3272. Montserrat 5200
  3273. Anguilla 11300
  3274. Tuvalu 11300
  3275. dtype: int64
  3276. The `n` smallest elements where ``n=3`` with all duplicates kept. Note
  3277. that the returned Series has four elements due to the three duplicates.
  3278. >>> s.nsmallest(3, keep='all')
  3279. Montserrat 5200
  3280. Nauru 11300
  3281. Tuvalu 11300
  3282. Anguilla 11300
  3283. dtype: int64
  3284. """
  3285. return algorithms.SelectNSeries(self, n=n, keep=keep).nsmallest()
  3286. @doc(
  3287. klass=_shared_doc_kwargs["klass"],
  3288. extra_params=dedent(
  3289. """copy : bool, default True
  3290. Whether to copy underlying data."""
  3291. ),
  3292. examples=dedent(
  3293. """Examples
  3294. --------
  3295. >>> s = pd.Series(
  3296. ... ["A", "B", "A", "C"],
  3297. ... index=[
  3298. ... ["Final exam", "Final exam", "Coursework", "Coursework"],
  3299. ... ["History", "Geography", "History", "Geography"],
  3300. ... ["January", "February", "March", "April"],
  3301. ... ],
  3302. ... )
  3303. >>> s
  3304. Final exam History January A
  3305. Geography February B
  3306. Coursework History March A
  3307. Geography April C
  3308. dtype: object
  3309. In the following example, we will swap the levels of the indices.
  3310. Here, we will swap the levels column-wise, but levels can be swapped row-wise
  3311. in a similar manner. Note that column-wise is the default behaviour.
  3312. By not supplying any arguments for i and j, we swap the last and second to
  3313. last indices.
  3314. >>> s.swaplevel()
  3315. Final exam January History A
  3316. February Geography B
  3317. Coursework March History A
  3318. April Geography C
  3319. dtype: object
  3320. By supplying one argument, we can choose which index to swap the last
  3321. index with. We can for example swap the first index with the last one as
  3322. follows.
  3323. >>> s.swaplevel(0)
  3324. January History Final exam A
  3325. February Geography Final exam B
  3326. March History Coursework A
  3327. April Geography Coursework C
  3328. dtype: object
  3329. We can also define explicitly which indices we want to swap by supplying values
  3330. for both i and j. Here, we for example swap the first and second indices.
  3331. >>> s.swaplevel(0, 1)
  3332. History Final exam January A
  3333. Geography Final exam February B
  3334. History Coursework March A
  3335. Geography Coursework April C
  3336. dtype: object"""
  3337. ),
  3338. )
  3339. def swaplevel(self, i=-2, j=-1, copy=True) -> Series:
  3340. """
  3341. Swap levels i and j in a :class:`MultiIndex`.
  3342. Default is to swap the two innermost levels of the index.
  3343. Parameters
  3344. ----------
  3345. i, j : int or str
  3346. Levels of the indices to be swapped. Can pass level name as string.
  3347. {extra_params}
  3348. Returns
  3349. -------
  3350. {klass}
  3351. {klass} with levels swapped in MultiIndex.
  3352. {examples}
  3353. """
  3354. assert isinstance(self.index, MultiIndex)
  3355. new_index = self.index.swaplevel(i, j)
  3356. return self._constructor(self._values, index=new_index, copy=copy).__finalize__(
  3357. self, method="swaplevel"
  3358. )
  3359. def reorder_levels(self, order) -> Series:
  3360. """
  3361. Rearrange index levels using input order.
  3362. May not drop or duplicate levels.
  3363. Parameters
  3364. ----------
  3365. order : list of int representing new level order
  3366. Reference level by number or key.
  3367. Returns
  3368. -------
  3369. type of caller (new object)
  3370. """
  3371. if not isinstance(self.index, MultiIndex): # pragma: no cover
  3372. raise Exception("Can only reorder levels on a hierarchical axis.")
  3373. result = self.copy()
  3374. assert isinstance(result.index, MultiIndex)
  3375. result.index = result.index.reorder_levels(order)
  3376. return result
  3377. def explode(self, ignore_index: bool = False) -> Series:
  3378. """
  3379. Transform each element of a list-like to a row.
  3380. .. versionadded:: 0.25.0
  3381. Parameters
  3382. ----------
  3383. ignore_index : bool, default False
  3384. If True, the resulting index will be labeled 0, 1, …, n - 1.
  3385. .. versionadded:: 1.1.0
  3386. Returns
  3387. -------
  3388. Series
  3389. Exploded lists to rows; index will be duplicated for these rows.
  3390. See Also
  3391. --------
  3392. Series.str.split : Split string values on specified separator.
  3393. Series.unstack : Unstack, a.k.a. pivot, Series with MultiIndex
  3394. to produce DataFrame.
  3395. DataFrame.melt : Unpivot a DataFrame from wide format to long format.
  3396. DataFrame.explode : Explode a DataFrame from list-like
  3397. columns to long format.
  3398. Notes
  3399. -----
  3400. This routine will explode list-likes including lists, tuples, sets,
  3401. Series, and np.ndarray. The result dtype of the subset rows will
  3402. be object. Scalars will be returned unchanged, and empty list-likes will
  3403. result in a np.nan for that row. In addition, the ordering of elements in
  3404. the output will be non-deterministic when exploding sets.
  3405. Examples
  3406. --------
  3407. >>> s = pd.Series([[1, 2, 3], 'foo', [], [3, 4]])
  3408. >>> s
  3409. 0 [1, 2, 3]
  3410. 1 foo
  3411. 2 []
  3412. 3 [3, 4]
  3413. dtype: object
  3414. >>> s.explode()
  3415. 0 1
  3416. 0 2
  3417. 0 3
  3418. 1 foo
  3419. 2 NaN
  3420. 3 3
  3421. 3 4
  3422. dtype: object
  3423. """
  3424. if not len(self) or not is_object_dtype(self):
  3425. result = self.copy()
  3426. return result.reset_index(drop=True) if ignore_index else result
  3427. values, counts = reshape.explode(np.asarray(self._values))
  3428. if ignore_index:
  3429. index = default_index(len(values))
  3430. else:
  3431. index = self.index.repeat(counts)
  3432. return self._constructor(values, index=index, name=self.name)
  3433. def unstack(self, level=-1, fill_value=None) -> DataFrame:
  3434. """
  3435. Unstack, also known as pivot, Series with MultiIndex to produce DataFrame.
  3436. Parameters
  3437. ----------
  3438. level : int, str, or list of these, default last level
  3439. Level(s) to unstack, can pass level name.
  3440. fill_value : scalar value, default None
  3441. Value to use when replacing NaN values.
  3442. Returns
  3443. -------
  3444. DataFrame
  3445. Unstacked Series.
  3446. Examples
  3447. --------
  3448. >>> s = pd.Series([1, 2, 3, 4],
  3449. ... index=pd.MultiIndex.from_product([['one', 'two'],
  3450. ... ['a', 'b']]))
  3451. >>> s
  3452. one a 1
  3453. b 2
  3454. two a 3
  3455. b 4
  3456. dtype: int64
  3457. >>> s.unstack(level=-1)
  3458. a b
  3459. one 1 2
  3460. two 3 4
  3461. >>> s.unstack(level=0)
  3462. one two
  3463. a 1 3
  3464. b 2 4
  3465. """
  3466. from pandas.core.reshape.reshape import unstack
  3467. return unstack(self, level, fill_value)
  3468. # ----------------------------------------------------------------------
  3469. # function application
  3470. def map(self, arg, na_action=None) -> Series:
  3471. """
  3472. Map values of Series according to input correspondence.
  3473. Used for substituting each value in a Series with another value,
  3474. that may be derived from a function, a ``dict`` or
  3475. a :class:`Series`.
  3476. Parameters
  3477. ----------
  3478. arg : function, collections.abc.Mapping subclass or Series
  3479. Mapping correspondence.
  3480. na_action : {None, 'ignore'}, default None
  3481. If 'ignore', propagate NaN values, without passing them to the
  3482. mapping correspondence.
  3483. Returns
  3484. -------
  3485. Series
  3486. Same index as caller.
  3487. See Also
  3488. --------
  3489. Series.apply : For applying more complex functions on a Series.
  3490. DataFrame.apply : Apply a function row-/column-wise.
  3491. DataFrame.applymap : Apply a function elementwise on a whole DataFrame.
  3492. Notes
  3493. -----
  3494. When ``arg`` is a dictionary, values in Series that are not in the
  3495. dictionary (as keys) are converted to ``NaN``. However, if the
  3496. dictionary is a ``dict`` subclass that defines ``__missing__`` (i.e.
  3497. provides a method for default values), then this default is used
  3498. rather than ``NaN``.
  3499. Examples
  3500. --------
  3501. >>> s = pd.Series(['cat', 'dog', np.nan, 'rabbit'])
  3502. >>> s
  3503. 0 cat
  3504. 1 dog
  3505. 2 NaN
  3506. 3 rabbit
  3507. dtype: object
  3508. ``map`` accepts a ``dict`` or a ``Series``. Values that are not found
  3509. in the ``dict`` are converted to ``NaN``, unless the dict has a default
  3510. value (e.g. ``defaultdict``):
  3511. >>> s.map({'cat': 'kitten', 'dog': 'puppy'})
  3512. 0 kitten
  3513. 1 puppy
  3514. 2 NaN
  3515. 3 NaN
  3516. dtype: object
  3517. It also accepts a function:
  3518. >>> s.map('I am a {}'.format)
  3519. 0 I am a cat
  3520. 1 I am a dog
  3521. 2 I am a nan
  3522. 3 I am a rabbit
  3523. dtype: object
  3524. To avoid applying the function to missing values (and keep them as
  3525. ``NaN``) ``na_action='ignore'`` can be used:
  3526. >>> s.map('I am a {}'.format, na_action='ignore')
  3527. 0 I am a cat
  3528. 1 I am a dog
  3529. 2 NaN
  3530. 3 I am a rabbit
  3531. dtype: object
  3532. """
  3533. new_values = self._map_values(arg, na_action=na_action)
  3534. return self._constructor(new_values, index=self.index).__finalize__(
  3535. self, method="map"
  3536. )
  3537. def _gotitem(self, key, ndim, subset=None) -> Series:
  3538. """
  3539. Sub-classes to define. Return a sliced object.
  3540. Parameters
  3541. ----------
  3542. key : string / list of selections
  3543. ndim : {1, 2}
  3544. Requested ndim of result.
  3545. subset : object, default None
  3546. Subset to act on.
  3547. """
  3548. return self
  3549. _agg_see_also_doc = dedent(
  3550. """
  3551. See Also
  3552. --------
  3553. Series.apply : Invoke function on a Series.
  3554. Series.transform : Transform function producing a Series with like indexes.
  3555. """
  3556. )
  3557. _agg_examples_doc = dedent(
  3558. """
  3559. Examples
  3560. --------
  3561. >>> s = pd.Series([1, 2, 3, 4])
  3562. >>> s
  3563. 0 1
  3564. 1 2
  3565. 2 3
  3566. 3 4
  3567. dtype: int64
  3568. >>> s.agg('min')
  3569. 1
  3570. >>> s.agg(['min', 'max'])
  3571. min 1
  3572. max 4
  3573. dtype: int64
  3574. """
  3575. )
  3576. @doc(
  3577. generic._shared_docs["aggregate"],
  3578. klass=_shared_doc_kwargs["klass"],
  3579. axis=_shared_doc_kwargs["axis"],
  3580. see_also=_agg_see_also_doc,
  3581. examples=_agg_examples_doc,
  3582. )
  3583. def aggregate(self, func=None, axis=0, *args, **kwargs):
  3584. # Validate the axis parameter
  3585. self._get_axis_number(axis)
  3586. # if func is None, will switch to user-provided "named aggregation" kwargs
  3587. if func is None:
  3588. func = dict(kwargs.items())
  3589. op = SeriesApply(self, func, convert_dtype=False, args=args, kwargs=kwargs)
  3590. result = op.agg()
  3591. return result
  3592. agg = aggregate
  3593. @doc(
  3594. _shared_docs["transform"],
  3595. klass=_shared_doc_kwargs["klass"],
  3596. axis=_shared_doc_kwargs["axis"],
  3597. )
  3598. def transform(
  3599. self, func: AggFuncType, axis: Axis = 0, *args, **kwargs
  3600. ) -> DataFrame | Series:
  3601. # Validate axis argument
  3602. self._get_axis_number(axis)
  3603. result = SeriesApply(
  3604. self, func=func, convert_dtype=True, args=args, kwargs=kwargs
  3605. ).transform()
  3606. return result
  3607. def apply(
  3608. self,
  3609. func: AggFuncType,
  3610. convert_dtype: bool = True,
  3611. args: tuple[Any, ...] = (),
  3612. **kwargs,
  3613. ) -> DataFrame | Series:
  3614. """
  3615. Invoke function on values of Series.
  3616. Can be ufunc (a NumPy function that applies to the entire Series)
  3617. or a Python function that only works on single values.
  3618. Parameters
  3619. ----------
  3620. func : function
  3621. Python function or NumPy ufunc to apply.
  3622. convert_dtype : bool, default True
  3623. Try to find better dtype for elementwise function results. If
  3624. False, leave as dtype=object. Note that the dtype is always
  3625. preserved for some extension array dtypes, such as Categorical.
  3626. args : tuple
  3627. Positional arguments passed to func after the series value.
  3628. **kwargs
  3629. Additional keyword arguments passed to func.
  3630. Returns
  3631. -------
  3632. Series or DataFrame
  3633. If func returns a Series object the result will be a DataFrame.
  3634. See Also
  3635. --------
  3636. Series.map: For element-wise operations.
  3637. Series.agg: Only perform aggregating type operations.
  3638. Series.transform: Only perform transforming type operations.
  3639. Notes
  3640. -----
  3641. Functions that mutate the passed object can produce unexpected
  3642. behavior or errors and are not supported. See :ref:`gotchas.udf-mutation`
  3643. for more details.
  3644. Examples
  3645. --------
  3646. Create a series with typical summer temperatures for each city.
  3647. >>> s = pd.Series([20, 21, 12],
  3648. ... index=['London', 'New York', 'Helsinki'])
  3649. >>> s
  3650. London 20
  3651. New York 21
  3652. Helsinki 12
  3653. dtype: int64
  3654. Square the values by defining a function and passing it as an
  3655. argument to ``apply()``.
  3656. >>> def square(x):
  3657. ... return x ** 2
  3658. >>> s.apply(square)
  3659. London 400
  3660. New York 441
  3661. Helsinki 144
  3662. dtype: int64
  3663. Square the values by passing an anonymous function as an
  3664. argument to ``apply()``.
  3665. >>> s.apply(lambda x: x ** 2)
  3666. London 400
  3667. New York 441
  3668. Helsinki 144
  3669. dtype: int64
  3670. Define a custom function that needs additional positional
  3671. arguments and pass these additional arguments using the
  3672. ``args`` keyword.
  3673. >>> def subtract_custom_value(x, custom_value):
  3674. ... return x - custom_value
  3675. >>> s.apply(subtract_custom_value, args=(5,))
  3676. London 15
  3677. New York 16
  3678. Helsinki 7
  3679. dtype: int64
  3680. Define a custom function that takes keyword arguments
  3681. and pass these arguments to ``apply``.
  3682. >>> def add_custom_values(x, **kwargs):
  3683. ... for month in kwargs:
  3684. ... x += kwargs[month]
  3685. ... return x
  3686. >>> s.apply(add_custom_values, june=30, july=20, august=25)
  3687. London 95
  3688. New York 96
  3689. Helsinki 87
  3690. dtype: int64
  3691. Use a function from the Numpy library.
  3692. >>> s.apply(np.log)
  3693. London 2.995732
  3694. New York 3.044522
  3695. Helsinki 2.484907
  3696. dtype: float64
  3697. """
  3698. return SeriesApply(self, func, convert_dtype, args, kwargs).apply()
  3699. def _reduce(
  3700. self,
  3701. op,
  3702. name: str,
  3703. *,
  3704. axis=0,
  3705. skipna=True,
  3706. numeric_only=None,
  3707. filter_type=None,
  3708. **kwds,
  3709. ):
  3710. """
  3711. Perform a reduction operation.
  3712. If we have an ndarray as a value, then simply perform the operation,
  3713. otherwise delegate to the object.
  3714. """
  3715. delegate = self._values
  3716. if axis is not None:
  3717. self._get_axis_number(axis)
  3718. if isinstance(delegate, ExtensionArray):
  3719. # dispatch to ExtensionArray interface
  3720. return delegate._reduce(name, skipna=skipna, **kwds)
  3721. else:
  3722. # dispatch to numpy arrays
  3723. if numeric_only:
  3724. kwd_name = "numeric_only"
  3725. if name in ["any", "all"]:
  3726. kwd_name = "bool_only"
  3727. raise NotImplementedError(
  3728. f"Series.{name} does not implement {kwd_name}."
  3729. )
  3730. with np.errstate(all="ignore"):
  3731. return op(delegate, skipna=skipna, **kwds)
  3732. def _reindex_indexer(
  3733. self, new_index: Index | None, indexer: npt.NDArray[np.intp] | None, copy: bool
  3734. ) -> Series:
  3735. # Note: new_index is None iff indexer is None
  3736. # if not None, indexer is np.intp
  3737. if indexer is None:
  3738. if copy:
  3739. return self.copy()
  3740. return self
  3741. new_values = algorithms.take_nd(
  3742. self._values, indexer, allow_fill=True, fill_value=None
  3743. )
  3744. return self._constructor(new_values, index=new_index)
  3745. def _needs_reindex_multi(self, axes, method, level) -> bool:
  3746. """
  3747. Check if we do need a multi reindex; this is for compat with
  3748. higher dims.
  3749. """
  3750. return False
  3751. # error: Cannot determine type of 'align'
  3752. @doc(
  3753. NDFrame.align, # type: ignore[has-type]
  3754. klass=_shared_doc_kwargs["klass"],
  3755. axes_single_arg=_shared_doc_kwargs["axes_single_arg"],
  3756. )
  3757. def align(
  3758. self,
  3759. other,
  3760. join="outer",
  3761. axis=None,
  3762. level=None,
  3763. copy=True,
  3764. fill_value=None,
  3765. method=None,
  3766. limit=None,
  3767. fill_axis=0,
  3768. broadcast_axis=None,
  3769. ):
  3770. return super().align(
  3771. other,
  3772. join=join,
  3773. axis=axis,
  3774. level=level,
  3775. copy=copy,
  3776. fill_value=fill_value,
  3777. method=method,
  3778. limit=limit,
  3779. fill_axis=fill_axis,
  3780. broadcast_axis=broadcast_axis,
  3781. )
  3782. def rename(
  3783. self,
  3784. index=None,
  3785. *,
  3786. axis=None,
  3787. copy=True,
  3788. inplace=False,
  3789. level=None,
  3790. errors="ignore",
  3791. ):
  3792. """
  3793. Alter Series index labels or name.
  3794. Function / dict values must be unique (1-to-1). Labels not contained in
  3795. a dict / Series will be left as-is. Extra labels listed don't throw an
  3796. error.
  3797. Alternatively, change ``Series.name`` with a scalar value.
  3798. See the :ref:`user guide <basics.rename>` for more.
  3799. Parameters
  3800. ----------
  3801. axis : {0 or "index"}
  3802. Unused. Accepted for compatibility with DataFrame method only.
  3803. index : scalar, hashable sequence, dict-like or function, optional
  3804. Functions or dict-like are transformations to apply to
  3805. the index.
  3806. Scalar or hashable sequence-like will alter the ``Series.name``
  3807. attribute.
  3808. **kwargs
  3809. Additional keyword arguments passed to the function. Only the
  3810. "inplace" keyword is used.
  3811. Returns
  3812. -------
  3813. Series or None
  3814. Series with index labels or name altered or None if ``inplace=True``.
  3815. See Also
  3816. --------
  3817. DataFrame.rename : Corresponding DataFrame method.
  3818. Series.rename_axis : Set the name of the axis.
  3819. Examples
  3820. --------
  3821. >>> s = pd.Series([1, 2, 3])
  3822. >>> s
  3823. 0 1
  3824. 1 2
  3825. 2 3
  3826. dtype: int64
  3827. >>> s.rename("my_name") # scalar, changes Series.name
  3828. 0 1
  3829. 1 2
  3830. 2 3
  3831. Name: my_name, dtype: int64
  3832. >>> s.rename(lambda x: x ** 2) # function, changes labels
  3833. 0 1
  3834. 1 2
  3835. 4 3
  3836. dtype: int64
  3837. >>> s.rename({1: 3, 2: 5}) # mapping, changes labels
  3838. 0 1
  3839. 3 2
  3840. 5 3
  3841. dtype: int64
  3842. """
  3843. if axis is not None:
  3844. # Make sure we raise if an invalid 'axis' is passed.
  3845. axis = self._get_axis_number(axis)
  3846. if callable(index) or is_dict_like(index):
  3847. return super().rename(
  3848. index, copy=copy, inplace=inplace, level=level, errors=errors
  3849. )
  3850. else:
  3851. return self._set_name(index, inplace=inplace)
  3852. @overload
  3853. def set_axis(
  3854. self, labels, axis: Axis = ..., inplace: Literal[False] = ...
  3855. ) -> Series:
  3856. ...
  3857. @overload
  3858. def set_axis(self, labels, axis: Axis, inplace: Literal[True]) -> None:
  3859. ...
  3860. @overload
  3861. def set_axis(self, labels, *, inplace: Literal[True]) -> None:
  3862. ...
  3863. @overload
  3864. def set_axis(self, labels, axis: Axis = ..., inplace: bool = ...) -> Series | None:
  3865. ...
  3866. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"])
  3867. @Appender(
  3868. """
  3869. Examples
  3870. --------
  3871. >>> s = pd.Series([1, 2, 3])
  3872. >>> s
  3873. 0 1
  3874. 1 2
  3875. 2 3
  3876. dtype: int64
  3877. >>> s.set_axis(['a', 'b', 'c'], axis=0)
  3878. a 1
  3879. b 2
  3880. c 3
  3881. dtype: int64
  3882. """
  3883. )
  3884. @Substitution(
  3885. **_shared_doc_kwargs,
  3886. extended_summary_sub="",
  3887. axis_description_sub="",
  3888. see_also_sub="",
  3889. )
  3890. @Appender(generic.NDFrame.set_axis.__doc__)
  3891. def set_axis(self, labels, axis: Axis = 0, inplace: bool = False):
  3892. return super().set_axis(labels, axis=axis, inplace=inplace)
  3893. # error: Cannot determine type of 'reindex'
  3894. @doc(
  3895. NDFrame.reindex, # type: ignore[has-type]
  3896. klass=_shared_doc_kwargs["klass"],
  3897. axes=_shared_doc_kwargs["axes"],
  3898. optional_labels=_shared_doc_kwargs["optional_labels"],
  3899. optional_axis=_shared_doc_kwargs["optional_axis"],
  3900. )
  3901. def reindex(self, index=None, **kwargs):
  3902. return super().reindex(index=index, **kwargs)
  3903. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "labels"])
  3904. def drop(
  3905. self,
  3906. labels=None,
  3907. axis=0,
  3908. index=None,
  3909. columns=None,
  3910. level=None,
  3911. inplace=False,
  3912. errors="raise",
  3913. ) -> Series:
  3914. """
  3915. Return Series with specified index labels removed.
  3916. Remove elements of a Series based on specifying the index labels.
  3917. When using a multi-index, labels on different levels can be removed
  3918. by specifying the level.
  3919. Parameters
  3920. ----------
  3921. labels : single label or list-like
  3922. Index labels to drop.
  3923. axis : 0, default 0
  3924. Redundant for application on Series.
  3925. index : single label or list-like
  3926. Redundant for application on Series, but 'index' can be used instead
  3927. of 'labels'.
  3928. columns : single label or list-like
  3929. No change is made to the Series; use 'index' or 'labels' instead.
  3930. level : int or level name, optional
  3931. For MultiIndex, level for which the labels will be removed.
  3932. inplace : bool, default False
  3933. If True, do operation inplace and return None.
  3934. errors : {'ignore', 'raise'}, default 'raise'
  3935. If 'ignore', suppress error and only existing labels are dropped.
  3936. Returns
  3937. -------
  3938. Series or None
  3939. Series with specified index labels removed or None if ``inplace=True``.
  3940. Raises
  3941. ------
  3942. KeyError
  3943. If none of the labels are found in the index.
  3944. See Also
  3945. --------
  3946. Series.reindex : Return only specified index labels of Series.
  3947. Series.dropna : Return series without null values.
  3948. Series.drop_duplicates : Return Series with duplicate values removed.
  3949. DataFrame.drop : Drop specified labels from rows or columns.
  3950. Examples
  3951. --------
  3952. >>> s = pd.Series(data=np.arange(3), index=['A', 'B', 'C'])
  3953. >>> s
  3954. A 0
  3955. B 1
  3956. C 2
  3957. dtype: int64
  3958. Drop labels B en C
  3959. >>> s.drop(labels=['B', 'C'])
  3960. A 0
  3961. dtype: int64
  3962. Drop 2nd level label in MultiIndex Series
  3963. >>> midx = pd.MultiIndex(levels=[['lama', 'cow', 'falcon'],
  3964. ... ['speed', 'weight', 'length']],
  3965. ... codes=[[0, 0, 0, 1, 1, 1, 2, 2, 2],
  3966. ... [0, 1, 2, 0, 1, 2, 0, 1, 2]])
  3967. >>> s = pd.Series([45, 200, 1.2, 30, 250, 1.5, 320, 1, 0.3],
  3968. ... index=midx)
  3969. >>> s
  3970. lama speed 45.0
  3971. weight 200.0
  3972. length 1.2
  3973. cow speed 30.0
  3974. weight 250.0
  3975. length 1.5
  3976. falcon speed 320.0
  3977. weight 1.0
  3978. length 0.3
  3979. dtype: float64
  3980. >>> s.drop(labels='weight', level=1)
  3981. lama speed 45.0
  3982. length 1.2
  3983. cow speed 30.0
  3984. length 1.5
  3985. falcon speed 320.0
  3986. length 0.3
  3987. dtype: float64
  3988. """
  3989. return super().drop(
  3990. labels=labels,
  3991. axis=axis,
  3992. index=index,
  3993. columns=columns,
  3994. level=level,
  3995. inplace=inplace,
  3996. errors=errors,
  3997. )
  3998. @overload
  3999. def fillna(
  4000. self,
  4001. value=...,
  4002. method: FillnaOptions | None = ...,
  4003. axis: Axis | None = ...,
  4004. inplace: Literal[False] = ...,
  4005. limit=...,
  4006. downcast=...,
  4007. ) -> Series:
  4008. ...
  4009. @overload
  4010. def fillna(
  4011. self,
  4012. value,
  4013. method: FillnaOptions | None,
  4014. axis: Axis | None,
  4015. inplace: Literal[True],
  4016. limit=...,
  4017. downcast=...,
  4018. ) -> None:
  4019. ...
  4020. @overload
  4021. def fillna(
  4022. self,
  4023. *,
  4024. inplace: Literal[True],
  4025. limit=...,
  4026. downcast=...,
  4027. ) -> None:
  4028. ...
  4029. @overload
  4030. def fillna(
  4031. self,
  4032. value,
  4033. *,
  4034. inplace: Literal[True],
  4035. limit=...,
  4036. downcast=...,
  4037. ) -> None:
  4038. ...
  4039. @overload
  4040. def fillna(
  4041. self,
  4042. *,
  4043. method: FillnaOptions | None,
  4044. inplace: Literal[True],
  4045. limit=...,
  4046. downcast=...,
  4047. ) -> None:
  4048. ...
  4049. @overload
  4050. def fillna(
  4051. self,
  4052. *,
  4053. axis: Axis | None,
  4054. inplace: Literal[True],
  4055. limit=...,
  4056. downcast=...,
  4057. ) -> None:
  4058. ...
  4059. @overload
  4060. def fillna(
  4061. self,
  4062. *,
  4063. method: FillnaOptions | None,
  4064. axis: Axis | None,
  4065. inplace: Literal[True],
  4066. limit=...,
  4067. downcast=...,
  4068. ) -> None:
  4069. ...
  4070. @overload
  4071. def fillna(
  4072. self,
  4073. value,
  4074. *,
  4075. axis: Axis | None,
  4076. inplace: Literal[True],
  4077. limit=...,
  4078. downcast=...,
  4079. ) -> None:
  4080. ...
  4081. @overload
  4082. def fillna(
  4083. self,
  4084. value,
  4085. method: FillnaOptions | None,
  4086. *,
  4087. inplace: Literal[True],
  4088. limit=...,
  4089. downcast=...,
  4090. ) -> None:
  4091. ...
  4092. @overload
  4093. def fillna(
  4094. self,
  4095. value=...,
  4096. method: FillnaOptions | None = ...,
  4097. axis: Axis | None = ...,
  4098. inplace: bool = ...,
  4099. limit=...,
  4100. downcast=...,
  4101. ) -> Series | None:
  4102. ...
  4103. # error: Cannot determine type of 'fillna'
  4104. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "value"])
  4105. @doc(NDFrame.fillna, **_shared_doc_kwargs) # type: ignore[has-type]
  4106. def fillna(
  4107. self,
  4108. value: object | ArrayLike | None = None,
  4109. method: FillnaOptions | None = None,
  4110. axis=None,
  4111. inplace=False,
  4112. limit=None,
  4113. downcast=None,
  4114. ) -> Series | None:
  4115. return super().fillna(
  4116. value=value,
  4117. method=method,
  4118. axis=axis,
  4119. inplace=inplace,
  4120. limit=limit,
  4121. downcast=downcast,
  4122. )
  4123. def pop(self, item: Hashable) -> Any:
  4124. """
  4125. Return item and drops from series. Raise KeyError if not found.
  4126. Parameters
  4127. ----------
  4128. item : label
  4129. Index of the element that needs to be removed.
  4130. Returns
  4131. -------
  4132. Value that is popped from series.
  4133. Examples
  4134. --------
  4135. >>> ser = pd.Series([1,2,3])
  4136. >>> ser.pop(0)
  4137. 1
  4138. >>> ser
  4139. 1 2
  4140. 2 3
  4141. dtype: int64
  4142. """
  4143. return super().pop(item=item)
  4144. # error: Cannot determine type of 'replace'
  4145. @doc(
  4146. NDFrame.replace, # type: ignore[has-type]
  4147. klass=_shared_doc_kwargs["klass"],
  4148. inplace=_shared_doc_kwargs["inplace"],
  4149. replace_iloc=_shared_doc_kwargs["replace_iloc"],
  4150. )
  4151. def replace(
  4152. self,
  4153. to_replace=None,
  4154. value=None,
  4155. inplace=False,
  4156. limit=None,
  4157. regex=False,
  4158. method="pad",
  4159. ):
  4160. return super().replace(
  4161. to_replace=to_replace,
  4162. value=value,
  4163. inplace=inplace,
  4164. limit=limit,
  4165. regex=regex,
  4166. method=method,
  4167. )
  4168. def _replace_single(self, to_replace, method: str, inplace: bool, limit):
  4169. """
  4170. Replaces values in a Series using the fill method specified when no
  4171. replacement value is given in the replace method
  4172. """
  4173. result = self if inplace else self.copy()
  4174. values = result._values
  4175. mask = missing.mask_missing(values, to_replace)
  4176. if isinstance(values, ExtensionArray):
  4177. # dispatch to the EA's _pad_mask_inplace method
  4178. values._fill_mask_inplace(method, limit, mask)
  4179. else:
  4180. fill_f = missing.get_fill_func(method)
  4181. values, _ = fill_f(values, limit=limit, mask=mask)
  4182. if inplace:
  4183. return
  4184. return result
  4185. # error: Cannot determine type of 'shift'
  4186. @doc(NDFrame.shift, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  4187. def shift(self, periods=1, freq=None, axis=0, fill_value=None) -> Series:
  4188. return super().shift(
  4189. periods=periods, freq=freq, axis=axis, fill_value=fill_value
  4190. )
  4191. def memory_usage(self, index: bool = True, deep: bool = False) -> int:
  4192. """
  4193. Return the memory usage of the Series.
  4194. The memory usage can optionally include the contribution of
  4195. the index and of elements of `object` dtype.
  4196. Parameters
  4197. ----------
  4198. index : bool, default True
  4199. Specifies whether to include the memory usage of the Series index.
  4200. deep : bool, default False
  4201. If True, introspect the data deeply by interrogating
  4202. `object` dtypes for system-level memory consumption, and include
  4203. it in the returned value.
  4204. Returns
  4205. -------
  4206. int
  4207. Bytes of memory consumed.
  4208. See Also
  4209. --------
  4210. numpy.ndarray.nbytes : Total bytes consumed by the elements of the
  4211. array.
  4212. DataFrame.memory_usage : Bytes consumed by a DataFrame.
  4213. Examples
  4214. --------
  4215. >>> s = pd.Series(range(3))
  4216. >>> s.memory_usage()
  4217. 152
  4218. Not including the index gives the size of the rest of the data, which
  4219. is necessarily smaller:
  4220. >>> s.memory_usage(index=False)
  4221. 24
  4222. The memory footprint of `object` values is ignored by default:
  4223. >>> s = pd.Series(["a", "b"])
  4224. >>> s.values
  4225. array(['a', 'b'], dtype=object)
  4226. >>> s.memory_usage()
  4227. 144
  4228. >>> s.memory_usage(deep=True)
  4229. 244
  4230. """
  4231. v = self._memory_usage(deep=deep)
  4232. if index:
  4233. v += self.index.memory_usage(deep=deep)
  4234. return v
  4235. def isin(self, values) -> Series:
  4236. """
  4237. Whether elements in Series are contained in `values`.
  4238. Return a boolean Series showing whether each element in the Series
  4239. matches an element in the passed sequence of `values` exactly.
  4240. Parameters
  4241. ----------
  4242. values : set or list-like
  4243. The sequence of values to test. Passing in a single string will
  4244. raise a ``TypeError``. Instead, turn a single string into a
  4245. list of one element.
  4246. Returns
  4247. -------
  4248. Series
  4249. Series of booleans indicating if each element is in values.
  4250. Raises
  4251. ------
  4252. TypeError
  4253. * If `values` is a string
  4254. See Also
  4255. --------
  4256. DataFrame.isin : Equivalent method on DataFrame.
  4257. Examples
  4258. --------
  4259. >>> s = pd.Series(['lama', 'cow', 'lama', 'beetle', 'lama',
  4260. ... 'hippo'], name='animal')
  4261. >>> s.isin(['cow', 'lama'])
  4262. 0 True
  4263. 1 True
  4264. 2 True
  4265. 3 False
  4266. 4 True
  4267. 5 False
  4268. Name: animal, dtype: bool
  4269. To invert the boolean values, use the ``~`` operator:
  4270. >>> ~s.isin(['cow', 'lama'])
  4271. 0 False
  4272. 1 False
  4273. 2 False
  4274. 3 True
  4275. 4 False
  4276. 5 True
  4277. Name: animal, dtype: bool
  4278. Passing a single string as ``s.isin('lama')`` will raise an error. Use
  4279. a list of one element instead:
  4280. >>> s.isin(['lama'])
  4281. 0 True
  4282. 1 False
  4283. 2 True
  4284. 3 False
  4285. 4 True
  4286. 5 False
  4287. Name: animal, dtype: bool
  4288. Strings and integers are distinct and are therefore not comparable:
  4289. >>> pd.Series([1]).isin(['1'])
  4290. 0 False
  4291. dtype: bool
  4292. >>> pd.Series([1.1]).isin(['1.1'])
  4293. 0 False
  4294. dtype: bool
  4295. """
  4296. result = algorithms.isin(self._values, values)
  4297. return self._constructor(result, index=self.index).__finalize__(
  4298. self, method="isin"
  4299. )
  4300. def between(self, left, right, inclusive="both") -> Series:
  4301. """
  4302. Return boolean Series equivalent to left <= series <= right.
  4303. This function returns a boolean vector containing `True` wherever the
  4304. corresponding Series element is between the boundary values `left` and
  4305. `right`. NA values are treated as `False`.
  4306. Parameters
  4307. ----------
  4308. left : scalar or list-like
  4309. Left boundary.
  4310. right : scalar or list-like
  4311. Right boundary.
  4312. inclusive : {"both", "neither", "left", "right"}
  4313. Include boundaries. Whether to set each bound as closed or open.
  4314. .. versionchanged:: 1.3.0
  4315. Returns
  4316. -------
  4317. Series
  4318. Series representing whether each element is between left and
  4319. right (inclusive).
  4320. See Also
  4321. --------
  4322. Series.gt : Greater than of series and other.
  4323. Series.lt : Less than of series and other.
  4324. Notes
  4325. -----
  4326. This function is equivalent to ``(left <= ser) & (ser <= right)``
  4327. Examples
  4328. --------
  4329. >>> s = pd.Series([2, 0, 4, 8, np.nan])
  4330. Boundary values are included by default:
  4331. >>> s.between(1, 4)
  4332. 0 True
  4333. 1 False
  4334. 2 True
  4335. 3 False
  4336. 4 False
  4337. dtype: bool
  4338. With `inclusive` set to ``"neither"`` boundary values are excluded:
  4339. >>> s.between(1, 4, inclusive="neither")
  4340. 0 True
  4341. 1 False
  4342. 2 False
  4343. 3 False
  4344. 4 False
  4345. dtype: bool
  4346. `left` and `right` can be any scalar value:
  4347. >>> s = pd.Series(['Alice', 'Bob', 'Carol', 'Eve'])
  4348. >>> s.between('Anna', 'Daniel')
  4349. 0 False
  4350. 1 True
  4351. 2 True
  4352. 3 False
  4353. dtype: bool
  4354. """
  4355. if inclusive is True or inclusive is False:
  4356. warnings.warn(
  4357. "Boolean inputs to the `inclusive` argument are deprecated in "
  4358. "favour of `both` or `neither`.",
  4359. FutureWarning,
  4360. stacklevel=2,
  4361. )
  4362. if inclusive:
  4363. inclusive = "both"
  4364. else:
  4365. inclusive = "neither"
  4366. if inclusive == "both":
  4367. lmask = self >= left
  4368. rmask = self <= right
  4369. elif inclusive == "left":
  4370. lmask = self >= left
  4371. rmask = self < right
  4372. elif inclusive == "right":
  4373. lmask = self > left
  4374. rmask = self <= right
  4375. elif inclusive == "neither":
  4376. lmask = self > left
  4377. rmask = self < right
  4378. else:
  4379. raise ValueError(
  4380. "Inclusive has to be either string of 'both',"
  4381. "'left', 'right', or 'neither'."
  4382. )
  4383. return lmask & rmask
  4384. # ----------------------------------------------------------------------
  4385. # Convert to types that support pd.NA
  4386. def _convert_dtypes(
  4387. self,
  4388. infer_objects: bool = True,
  4389. convert_string: bool = True,
  4390. convert_integer: bool = True,
  4391. convert_boolean: bool = True,
  4392. convert_floating: bool = True,
  4393. ) -> Series:
  4394. input_series = self
  4395. if infer_objects:
  4396. input_series = input_series.infer_objects()
  4397. if is_object_dtype(input_series):
  4398. input_series = input_series.copy()
  4399. if convert_string or convert_integer or convert_boolean or convert_floating:
  4400. inferred_dtype = convert_dtypes(
  4401. input_series._values,
  4402. convert_string,
  4403. convert_integer,
  4404. convert_boolean,
  4405. convert_floating,
  4406. )
  4407. result = input_series.astype(inferred_dtype)
  4408. else:
  4409. result = input_series.copy()
  4410. return result
  4411. # error: Cannot determine type of 'isna'
  4412. @doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  4413. def isna(self) -> Series:
  4414. return generic.NDFrame.isna(self)
  4415. # error: Cannot determine type of 'isna'
  4416. @doc(NDFrame.isna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  4417. def isnull(self) -> Series:
  4418. return super().isnull()
  4419. # error: Cannot determine type of 'notna'
  4420. @doc(NDFrame.notna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  4421. def notna(self) -> Series:
  4422. return super().notna()
  4423. # error: Cannot determine type of 'notna'
  4424. @doc(NDFrame.notna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
  4425. def notnull(self) -> Series:
  4426. return super().notnull()
  4427. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
  4428. def dropna(self, axis=0, inplace=False, how=None):
  4429. """
  4430. Return a new Series with missing values removed.
  4431. See the :ref:`User Guide <missing_data>` for more on which values are
  4432. considered missing, and how to work with missing data.
  4433. Parameters
  4434. ----------
  4435. axis : {0 or 'index'}, default 0
  4436. There is only one axis to drop values from.
  4437. inplace : bool, default False
  4438. If True, do operation inplace and return None.
  4439. how : str, optional
  4440. Not in use. Kept for compatibility.
  4441. Returns
  4442. -------
  4443. Series or None
  4444. Series with NA entries dropped from it or None if ``inplace=True``.
  4445. See Also
  4446. --------
  4447. Series.isna: Indicate missing values.
  4448. Series.notna : Indicate existing (non-missing) values.
  4449. Series.fillna : Replace missing values.
  4450. DataFrame.dropna : Drop rows or columns which contain NA values.
  4451. Index.dropna : Drop missing indices.
  4452. Examples
  4453. --------
  4454. >>> ser = pd.Series([1., 2., np.nan])
  4455. >>> ser
  4456. 0 1.0
  4457. 1 2.0
  4458. 2 NaN
  4459. dtype: float64
  4460. Drop NA values from a Series.
  4461. >>> ser.dropna()
  4462. 0 1.0
  4463. 1 2.0
  4464. dtype: float64
  4465. Keep the Series with valid entries in the same variable.
  4466. >>> ser.dropna(inplace=True)
  4467. >>> ser
  4468. 0 1.0
  4469. 1 2.0
  4470. dtype: float64
  4471. Empty strings are not considered NA values. ``None`` is considered an
  4472. NA value.
  4473. >>> ser = pd.Series([np.NaN, 2, pd.NaT, '', None, 'I stay'])
  4474. >>> ser
  4475. 0 NaN
  4476. 1 2
  4477. 2 NaT
  4478. 3
  4479. 4 None
  4480. 5 I stay
  4481. dtype: object
  4482. >>> ser.dropna()
  4483. 1 2
  4484. 3
  4485. 5 I stay
  4486. dtype: object
  4487. """
  4488. inplace = validate_bool_kwarg(inplace, "inplace")
  4489. # Validate the axis parameter
  4490. self._get_axis_number(axis or 0)
  4491. if self._can_hold_na:
  4492. result = remove_na_arraylike(self)
  4493. if inplace:
  4494. self._update_inplace(result)
  4495. else:
  4496. return result
  4497. else:
  4498. if inplace:
  4499. # do nothing
  4500. pass
  4501. else:
  4502. return self.copy()
  4503. # ----------------------------------------------------------------------
  4504. # Time series-oriented methods
  4505. # error: Cannot determine type of 'asfreq'
  4506. @doc(NDFrame.asfreq, **_shared_doc_kwargs) # type: ignore[has-type]
  4507. def asfreq(
  4508. self,
  4509. freq,
  4510. method=None,
  4511. how: str | None = None,
  4512. normalize: bool = False,
  4513. fill_value=None,
  4514. ) -> Series:
  4515. return super().asfreq(
  4516. freq=freq,
  4517. method=method,
  4518. how=how,
  4519. normalize=normalize,
  4520. fill_value=fill_value,
  4521. )
  4522. # error: Cannot determine type of 'resample'
  4523. @doc(NDFrame.resample, **_shared_doc_kwargs) # type: ignore[has-type]
  4524. def resample(
  4525. self,
  4526. rule,
  4527. axis=0,
  4528. closed: str | None = None,
  4529. label: str | None = None,
  4530. convention: str = "start",
  4531. kind: str | None = None,
  4532. loffset=None,
  4533. base: int | None = None,
  4534. on=None,
  4535. level=None,
  4536. origin: str | TimestampConvertibleTypes = "start_day",
  4537. offset: TimedeltaConvertibleTypes | None = None,
  4538. ) -> Resampler:
  4539. return super().resample(
  4540. rule=rule,
  4541. axis=axis,
  4542. closed=closed,
  4543. label=label,
  4544. convention=convention,
  4545. kind=kind,
  4546. loffset=loffset,
  4547. base=base,
  4548. on=on,
  4549. level=level,
  4550. origin=origin,
  4551. offset=offset,
  4552. )
  4553. def to_timestamp(self, freq=None, how="start", copy=True) -> Series:
  4554. """
  4555. Cast to DatetimeIndex of Timestamps, at *beginning* of period.
  4556. Parameters
  4557. ----------
  4558. freq : str, default frequency of PeriodIndex
  4559. Desired frequency.
  4560. how : {'s', 'e', 'start', 'end'}
  4561. Convention for converting period to timestamp; start of period
  4562. vs. end.
  4563. copy : bool, default True
  4564. Whether or not to return a copy.
  4565. Returns
  4566. -------
  4567. Series with DatetimeIndex
  4568. """
  4569. new_values = self._values
  4570. if copy:
  4571. new_values = new_values.copy()
  4572. if not isinstance(self.index, PeriodIndex):
  4573. raise TypeError(f"unsupported Type {type(self.index).__name__}")
  4574. new_index = self.index.to_timestamp(freq=freq, how=how)
  4575. return self._constructor(new_values, index=new_index).__finalize__(
  4576. self, method="to_timestamp"
  4577. )
  4578. def to_period(self, freq=None, copy=True) -> Series:
  4579. """
  4580. Convert Series from DatetimeIndex to PeriodIndex.
  4581. Parameters
  4582. ----------
  4583. freq : str, default None
  4584. Frequency associated with the PeriodIndex.
  4585. copy : bool, default True
  4586. Whether or not to return a copy.
  4587. Returns
  4588. -------
  4589. Series
  4590. Series with index converted to PeriodIndex.
  4591. """
  4592. new_values = self._values
  4593. if copy:
  4594. new_values = new_values.copy()
  4595. if not isinstance(self.index, DatetimeIndex):
  4596. raise TypeError(f"unsupported Type {type(self.index).__name__}")
  4597. new_index = self.index.to_period(freq=freq)
  4598. return self._constructor(new_values, index=new_index).__finalize__(
  4599. self, method="to_period"
  4600. )
  4601. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
  4602. def ffill(
  4603. self: Series,
  4604. axis: None | Axis = None,
  4605. inplace: bool = False,
  4606. limit: None | int = None,
  4607. downcast=None,
  4608. ) -> Series | None:
  4609. return super().ffill(axis, inplace, limit, downcast)
  4610. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self"])
  4611. def bfill(
  4612. self: Series,
  4613. axis: None | Axis = None,
  4614. inplace: bool = False,
  4615. limit: None | int = None,
  4616. downcast=None,
  4617. ) -> Series | None:
  4618. return super().bfill(axis, inplace, limit, downcast)
  4619. @deprecate_nonkeyword_arguments(
  4620. version=None, allowed_args=["self", "lower", "upper"]
  4621. )
  4622. def clip(
  4623. self: Series,
  4624. lower=None,
  4625. upper=None,
  4626. axis: Axis | None = None,
  4627. inplace: bool = False,
  4628. *args,
  4629. **kwargs,
  4630. ) -> Series | None:
  4631. return super().clip(lower, upper, axis, inplace, *args, **kwargs)
  4632. @deprecate_nonkeyword_arguments(version=None, allowed_args=["self", "method"])
  4633. def interpolate(
  4634. self: Series,
  4635. method: str = "linear",
  4636. axis: Axis = 0,
  4637. limit: int | None = None,
  4638. inplace: bool = False,
  4639. limit_direction: str | None = None,
  4640. limit_area: str | None = None,
  4641. downcast: str | None = None,
  4642. **kwargs,
  4643. ) -> Series | None:
  4644. return super().interpolate(
  4645. method,
  4646. axis,
  4647. limit,
  4648. inplace,
  4649. limit_direction,
  4650. limit_area,
  4651. downcast,
  4652. **kwargs,
  4653. )
  4654. @deprecate_nonkeyword_arguments(
  4655. version=None, allowed_args=["self", "cond", "other"]
  4656. )
  4657. def where(
  4658. self,
  4659. cond,
  4660. other=np.nan,
  4661. inplace=False,
  4662. axis=None,
  4663. level=None,
  4664. errors=lib.no_default,
  4665. try_cast=lib.no_default,
  4666. ):
  4667. return super().where(cond, other, inplace, axis, level, errors, try_cast)
  4668. @deprecate_nonkeyword_arguments(
  4669. version=None, allowed_args=["self", "cond", "other"]
  4670. )
  4671. def mask(
  4672. self,
  4673. cond,
  4674. other=np.nan,
  4675. inplace=False,
  4676. axis=None,
  4677. level=None,
  4678. errors=lib.no_default,
  4679. try_cast=lib.no_default,
  4680. ):
  4681. return super().mask(cond, other, inplace, axis, level, errors, try_cast)
  4682. # ----------------------------------------------------------------------
  4683. # Add index
  4684. _AXIS_ORDERS = ["index"]
  4685. _AXIS_LEN = len(_AXIS_ORDERS)
  4686. _info_axis_number = 0
  4687. _info_axis_name = "index"
  4688. index: Index = properties.AxisProperty(
  4689. axis=0, doc="The index (axis labels) of the Series."
  4690. )
  4691. # ----------------------------------------------------------------------
  4692. # Accessor Methods
  4693. # ----------------------------------------------------------------------
  4694. str = CachedAccessor("str", StringMethods)
  4695. dt = CachedAccessor("dt", CombinedDatetimelikeProperties)
  4696. cat = CachedAccessor("cat", CategoricalAccessor)
  4697. plot = CachedAccessor("plot", pandas.plotting.PlotAccessor)
  4698. sparse = CachedAccessor("sparse", SparseAccessor)
  4699. # ----------------------------------------------------------------------
  4700. # Add plotting methods to Series
  4701. hist = pandas.plotting.hist_series
  4702. # ----------------------------------------------------------------------
  4703. # Template-Based Arithmetic/Comparison Methods
  4704. def _cmp_method(self, other, op):
  4705. res_name = ops.get_op_result_name(self, other)
  4706. if isinstance(other, Series) and not self._indexed_same(other):
  4707. raise ValueError("Can only compare identically-labeled Series objects")
  4708. lvalues = self._values
  4709. rvalues = extract_array(other, extract_numpy=True, extract_range=True)
  4710. with np.errstate(all="ignore"):
  4711. res_values = ops.comparison_op(lvalues, rvalues, op)
  4712. return self._construct_result(res_values, name=res_name)
  4713. def _logical_method(self, other, op):
  4714. res_name = ops.get_op_result_name(self, other)
  4715. self, other = ops.align_method_SERIES(self, other, align_asobject=True)
  4716. lvalues = self._values
  4717. rvalues = extract_array(other, extract_numpy=True, extract_range=True)
  4718. res_values = ops.logical_op(lvalues, rvalues, op)
  4719. return self._construct_result(res_values, name=res_name)
  4720. def _arith_method(self, other, op):
  4721. self, other = ops.align_method_SERIES(self, other)
  4722. return base.IndexOpsMixin._arith_method(self, other, op)
  4723. Series._add_numeric_operations()
  4724. # Add arithmetic!
  4725. ops.add_flex_arithmetic_methods(Series)