Skip to content

Commit 029d57c

Browse files
tm9k1datapythonista
authored andcommitted
Added support for Fraction and Number (PEP 3141) to pandas.api.types.is_scalar (#22952)
1 parent 83c7e28 commit 029d57c

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

doc/source/whatsnew/v0.24.0.rst

+3
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ For situations where you need an ``ndarray`` of ``Interval`` objects, use
466466
np.asarray(idx)
467467
idx.values.astype(object)
468468
469+
469470
.. _whatsnew_0240.api.timezone_offset_parsing:
470471

471472
Parsing Datetime Strings with Timezone Offsets
@@ -1474,6 +1475,7 @@ Other
14741475
- :meth:`DataFrame.nlargest` and :meth:`DataFrame.nsmallest` now returns the correct n values when keep != 'all' also when tied on the first columns (:issue:`22752`)
14751476
- :meth:`~pandas.io.formats.style.Styler.bar` now also supports tablewise application (in addition to rowwise and columnwise) with ``axis=None`` and setting clipping range with ``vmin`` and ``vmax`` (:issue:`21548` and :issue:`21526`). ``NaN`` values are also handled properly.
14761477
- Logical operations ``&, |, ^`` between :class:`Series` and :class:`Index` will no longer raise ``ValueError`` (:issue:`22092`)
1478+
- Checking PEP 3141 numbers in :func:`~pandas.api.types.is_scalar` function returns ``True`` (:issue:`22903`)
14771479
- Bug in :meth:`DataFrame.combine_first` in which column types were unexpectedly converted to float (:issue:`20699`)
14781480

14791481
.. _whatsnew_0.24.0.contributors:
@@ -1482,3 +1484,4 @@ Contributors
14821484
~~~~~~~~~~~~
14831485

14841486
.. contributors:: v0.23.4..HEAD
1487+

pandas/_libs/lib.pyx

+46-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# -*- coding: utf-8 -*-
22
from decimal import Decimal
3+
from fractions import Fraction
4+
from numbers import Number
5+
36
import sys
47

58
import cython
@@ -15,7 +18,6 @@ from cpython.datetime cimport (PyDateTime_Check, PyDate_Check,
1518
PyDateTime_IMPORT)
1619
PyDateTime_IMPORT
1720

18-
1921
import numpy as np
2022
cimport numpy as cnp
2123
from numpy cimport (ndarray, PyArray_GETITEM,
@@ -105,23 +107,54 @@ def is_scalar(val: object) -> bool:
105107
"""
106108
Return True if given value is scalar.
107109

108-
This includes:
109-
- numpy array scalar (e.g. np.int64)
110-
- Python builtin numerics
111-
- Python builtin byte arrays and strings
112-
- None
113-
- instances of datetime.datetime
114-
- instances of datetime.timedelta
115-
- Period
116-
- instances of decimal.Decimal
117-
- Interval
118-
- DateOffset
110+
Parameters
111+
----------
112+
val : object
113+
This includes:
114+
115+
- numpy array scalar (e.g. np.int64)
116+
- Python builtin numerics
117+
- Python builtin byte arrays and strings
118+
- None
119+
- datetime.datetime
120+
- datetime.timedelta
121+
- Period
122+
- decimal.Decimal
123+
- Interval
124+
- DateOffset
125+
- Fraction
126+
- Number
127+
128+
Returns
129+
-------
130+
bool
131+
Return True if given object is scalar, False otherwise
132+
133+
Examples
134+
--------
135+
>>> dt = pd.datetime.datetime(2018, 10, 3)
136+
>>> pd.is_scalar(dt)
137+
True
138+
139+
>>> pd.api.types.is_scalar([2, 3])
140+
False
141+
142+
>>> pd.api.types.is_scalar({0: 1, 2: 3})
143+
False
144+
145+
>>> pd.api.types.is_scalar((0, 2))
146+
False
147+
148+
pandas supports PEP 3141 numbers:
119149

150+
>>> from fractions import Fraction
151+
>>> pd.api.types.is_scalar(Fraction(3, 5))
152+
True
120153
"""
121154

122155
return (cnp.PyArray_IsAnyScalar(val)
123156
# As of numpy-1.9, PyArray_IsAnyScalar misses bytearrays on Py3.
124-
or isinstance(val, bytes)
157+
or isinstance(val, (bytes, Fraction, Number))
125158
# We differ from numpy (as of 1.10), which claims that None is
126159
# not scalar in np.isscalar().
127160
or val is None

pandas/tests/dtypes/test_inference.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
import re
1111
from datetime import datetime, date, timedelta, time
1212
from decimal import Decimal
13+
from numbers import Number
14+
from fractions import Fraction
1315
import numpy as np
1416
import pytz
1517
import pytest
16-
1718
import pandas as pd
1819
from pandas._libs import lib, iNaT, missing as libmissing
1920
from pandas import (Series, Index, DataFrame, Timedelta,
@@ -1183,6 +1184,8 @@ def test_is_scalar_builtin_scalars(self):
11831184
assert is_scalar(None)
11841185
assert is_scalar(True)
11851186
assert is_scalar(False)
1187+
assert is_scalar(Number())
1188+
assert is_scalar(Fraction())
11861189
assert is_scalar(0.)
11871190
assert is_scalar(np.nan)
11881191
assert is_scalar('foobar')

0 commit comments

Comments
 (0)