1"""
2Common type operations.
3"""
4
5from __future__ import annotations
6
7from typing import (
8 TYPE_CHECKING,
9 Any,
10)
11import warnings
12
13import numpy as np
14
15from pandas._config import using_string_dtype
16
17from pandas._libs import (
18 Interval,
19 Period,
20 algos,
21 lib,
22)
23from pandas._libs.tslibs import conversion
24from pandas.errors import Pandas4Warning
25from pandas.util._decorators import set_module
26from pandas.util._exceptions import find_stack_level
27
28from pandas.core.dtypes.base import _registry as registry
29from pandas.core.dtypes.dtypes import (
30 ArrowDtype,
31 CategoricalDtype,
32 DatetimeTZDtype,
33 ExtensionDtype,
34 IntervalDtype,
35 PeriodDtype,
36 SparseDtype,
37)
38from pandas.core.dtypes.generic import (
39 ABCExtensionArray,
40 ABCIndex,
41 ABCNumpyExtensionArray,
42 ABCSeries,
43)
44from pandas.core.dtypes.inference import (
45 is_array_like,
46 is_bool,
47 is_complex,
48 is_dataclass,
49 is_decimal,
50 is_dict_like,
51 is_file_like,
52 is_float,
53 is_hashable,
54 is_integer,
55 is_iterator,
56 is_list_like,
57 is_named_tuple,
58 is_nested_list_like,
59 is_number,
60 is_re,
61 is_re_compilable,
62 is_scalar,
63 is_sequence,
64)
65
66if TYPE_CHECKING:
67 from collections.abc import Callable
68
69 from pandas._typing import (
70 ArrayLike,
71 DtypeObj,
72 )
73
74DT64NS_DTYPE = conversion.DT64NS_DTYPE
75TD64NS_DTYPE = conversion.TD64NS_DTYPE
76INT64_DTYPE = np.dtype(np.int64)
77
78# oh the troubles to reduce import time
79_is_scipy_sparse: Callable[[ArrayLike], bool] | None = None
80
81ensure_float64 = algos.ensure_float64
82ensure_int64 = algos.ensure_int64
83ensure_int32 = algos.ensure_int32
84ensure_int16 = algos.ensure_int16
85ensure_int8 = algos.ensure_int8
86ensure_platform_int = algos.ensure_platform_int
87ensure_object = algos.ensure_object
88ensure_uint64 = algos.ensure_uint64
89
90
91def is_array_like_deprecate_non_pandas(obj: object) -> bool:
92 """
93 Transitional replacement for ``is_array_like`` at internal call sites (GH#52834).
94
95 Returns the same value as ``is_array_like(obj)``, but emits a
96 :class:`Pandas4Warning` when ``obj`` qualifies as array-like only by
97 duck-typing (i.e. it has a ``dtype`` attribute but is not one of
98 ``ndarray``, ``ExtensionArray``, ``Index``, or ``Series``). These call
99 sites will eventually use ``isinstance(obj, (np.ndarray, ExtensionArray,
100 Index, Series))`` directly, at which point such objects will no longer be
101 treated as array-like. That isinstance check will need a ``ndim != 0``
102 carve-out for ndarray: ``is_array_like`` is False for 0-dimensional
103 ndarrays (effective scalars), and among these classes only ndarray can
104 be 0-dimensional.
105 """
106 if not is_array_like(obj):
107 return False
108 # Note: ABCExtensionArray excludes NumpyExtensionArray (_typ="npy_extension"),
109 # so ABCNumpyExtensionArray must be listed separately to cover all
110 # ExtensionArray subclasses.
111 if not isinstance(
112 obj,
113 (np.ndarray, ABCExtensionArray, ABCNumpyExtensionArray, ABCIndex, ABCSeries),
114 ):
115 warnings.warn(
116 "Treating an array-like object that is not a numpy ndarray, "
117 "ExtensionArray, Index, or Series as array-like is deprecated. In a "
118 "future version these objects will no longer be treated as "
119 "array-like; wrap the input in np.asarray, pd.array, or pd.Index "
120 "to retain the current behavior.",
121 Pandas4Warning,
122 stacklevel=find_stack_level(),
123 )
124 return True
125
126
127def ensure_str(value: bytes | Any) -> str:
128 """
129 Ensure that bytes and non-strings get converted into ``str`` objects.
130 """
131 if isinstance(value, bytes):
132 value = value.decode("utf-8")
133 elif not isinstance(value, str):
134 value = str(value)
135 return value
136
137
138def ensure_python_int(value: int | np.integer) -> int:
139 """
140 Ensure that a value is a python int.
141
142 Parameters
143 ----------
144 value: int or numpy.integer
145
146 Returns
147 -------
148 int
149
150 Raises
151 ------
152 TypeError: if the value isn't an int or can't be converted to one.
153 """
154 if not (is_integer(value) or is_float(value)):
155 if not is_scalar(value):
156 raise TypeError(
157 f"Value needs to be a scalar value, was type {type(value).__name__}"
158 )
159 raise TypeError(f"Wrong type {type(value)} for value {value}")
160 try:
161 new_value = int(value)
162 assert new_value == value
163 except (TypeError, ValueError, AssertionError) as err:
164 raise TypeError(f"Wrong type {type(value)} for value {value}") from err
165 return new_value
166
167
168def classes(*klasses) -> Callable[[type], bool]:
169 """Evaluate if the tipo is a subclass of the klasses."""
170 return lambda tipo: issubclass(tipo, klasses)
171
172
173def _classes_and_not_datetimelike(*klasses) -> Callable[[type], bool]:
174 """
175 Evaluate if the tipo is a subclass of the klasses
176 and not a datetimelike.
177 """
178 return lambda tipo: (
179 issubclass(tipo, klasses)
180 and not issubclass(tipo, (np.datetime64, np.timedelta64))
181 )
182
183
184@set_module("pandas.api.types")
185def is_object_dtype(arr_or_dtype) -> bool:
186 """
187 Check whether an array-like or dtype is of the object dtype.
188
189 This method examines the input to determine if it is of the
190 object data type. Object dtype is a generic data type that can
191 hold any Python objects, including strings, lists, and custom
192 objects.
193
194 Parameters
195 ----------
196 arr_or_dtype : array-like or dtype
197 The array-like or dtype to check.
198
199 Returns
200 -------
201 boolean
202 Whether or not the array-like or dtype is of the object dtype.
203
204 See Also
205 --------
206 api.types.is_numeric_dtype : Check whether the provided array or dtype is of a
207 numeric dtype.
208 api.types.is_string_dtype : Check whether the provided array or dtype is of
209 the string dtype.
210 api.types.is_bool_dtype : Check whether the provided array or dtype is of a
211 boolean dtype.
212
213 Examples
214 --------
215 >>> from pandas.api.types import is_object_dtype
216 >>> is_object_dtype(object)
217 True
218 >>> is_object_dtype(int)
219 False
220 >>> is_object_dtype(np.array([], dtype=object))
221 True
222 >>> is_object_dtype(np.array([], dtype=int))
223 False
224 >>> is_object_dtype([1, 2, 3])
225 False
226 """
227 return _is_dtype_type(arr_or_dtype, classes(np.object_))
228
229
230@set_module("pandas.api.types")
231def is_sparse(arr) -> bool:
232 """
233 Check whether an array-like is a 1-D pandas sparse array.
234
235 .. deprecated:: 2.1.0
236 Use isinstance(dtype, pd.SparseDtype) instead.
237
238 Check that the one-dimensional array-like is a pandas sparse array.
239 Returns True if it is a pandas sparse array, not another type of
240 sparse array.
241
242 Parameters
243 ----------
244 arr : array-like
245 Array-like to check.
246
247 Returns
248 -------
249 bool
250 Whether or not the array-like is a pandas sparse array.
251
252 See Also
253 --------
254 api.types.SparseDtype : The dtype object for pandas sparse arrays.
255
256 Examples
257 --------
258 Returns `True` if the parameter is a 1-D pandas sparse array.
259
260 >>> from pandas.api.types import is_sparse
261 >>> is_sparse(pd.arrays.SparseArray([0, 0, 1, 0]))
262 True
263 >>> is_sparse(pd.Series(pd.arrays.SparseArray([0, 0, 1, 0])))
264 True
265
266 Returns `False` if the parameter is not sparse.
267
268 >>> is_sparse(np.array([0, 0, 1, 0]))
269 False
270 >>> is_sparse(pd.Series([0, 1, 0, 0]))
271 False
272
273 Returns `False` if the parameter is not a pandas sparse array.
274
275 >>> from scipy.sparse import bsr_matrix
276 >>> is_sparse(bsr_matrix([0, 1, 0, 0]))
277 False
278
279 Returns `False` if the parameter has more than one dimension.
280 """
281 warnings.warn(
282 "is_sparse is deprecated and will be removed in a future "
283 "version. Check `isinstance(dtype, pd.SparseDtype)` instead.",
284 Pandas4Warning,
285 stacklevel=2,
286 )
287
288 dtype = getattr(arr, "dtype", arr)
289 return isinstance(dtype, SparseDtype)
290
291
292def is_scipy_sparse(arr) -> bool:
293 """
294 Check whether an array-like is a scipy.sparse.spmatrix instance.
295
296 Parameters
297 ----------
298 arr : array-like
299 The array-like to check.
300
301 Returns
302 -------
303 boolean
304 Whether or not the array-like is a scipy.sparse.spmatrix instance.
305
306 Notes
307 -----
308 If scipy is not installed, this function will always return False.
309
310 Examples
311 --------
312 >>> from scipy.sparse import bsr_matrix
313 >>> is_scipy_sparse(bsr_matrix([1, 2, 3]))
314 True
315 >>> is_scipy_sparse(pd.arrays.SparseArray([1, 2, 3]))
316 False
317 """
318 global _is_scipy_sparse
319
320 if _is_scipy_sparse is None:
321 try:
322 from scipy.sparse import issparse as _is_scipy_sparse
323 except ImportError:
324 _is_scipy_sparse = lambda _: False
325
326 assert _is_scipy_sparse is not None
327 return _is_scipy_sparse(arr)
328
329
330@set_module("pandas.api.types")
331def is_datetime64_dtype(arr_or_dtype) -> bool:
332 """
333 Check whether an array-like or dtype is of the datetime64 dtype.
334
335 This function checks for the base ``datetime64`` dtype without regard
336 to timezone information. For timezone-aware checks, use
337 :func:`api.types.is_datetime64_any_dtype` instead.
338
339 Parameters
340 ----------
341 arr_or_dtype : array-like or dtype
342 The array-like or dtype to check.
343
344 Returns
345 -------
346 boolean
347 Whether or not the array-like or dtype is of the datetime64 dtype.
348
349 See Also
350 --------
351 api.types.is_datetime64_ns_dtype: Check whether the provided array or
352 dtype is of the datetime64[ns] dtype.
353 api.types.is_datetime64_any_dtype: Check whether the provided array or
354 dtype is of the datetime64 dtype.
355
356 Examples
357 --------
358 >>> from pandas.api.types import is_datetime64_dtype
359 >>> is_datetime64_dtype(object)
360 False
361 >>> is_datetime64_dtype(np.datetime64)
362 True
363 >>> is_datetime64_dtype(np.array([], dtype=int))
364 False
365 >>> is_datetime64_dtype(np.array([], dtype=np.datetime64))
366 True
367 >>> is_datetime64_dtype([1, 2, 3])
368 False
369 """
370 if isinstance(arr_or_dtype, np.dtype):
371 # GH#33400 fastpath for dtype object
372 return arr_or_dtype.kind == "M"
373 return _is_dtype_type(arr_or_dtype, classes(np.datetime64))
374
375
376@set_module("pandas.api.types")
377def is_datetime64tz_dtype(arr_or_dtype) -> bool:
378 """
379 Check whether an array-like or dtype is of a DatetimeTZDtype dtype.
380
381 .. deprecated:: 2.1.0
382 Use isinstance(dtype, pd.DatetimeTZDtype) instead.
383
384 Parameters
385 ----------
386 arr_or_dtype : array-like or dtype
387 The array-like or dtype to check.
388
389 Returns
390 -------
391 boolean
392 Whether or not the array-like or dtype is of a DatetimeTZDtype dtype.
393
394 See Also
395 --------
396 api.types.is_datetime64_dtype: Check whether an array-like or
397 dtype is of the datetime64 dtype.
398 api.types.is_datetime64_any_dtype: Check whether the provided array or
399 dtype is of the datetime64 dtype.
400
401 Examples
402 --------
403 >>> from pandas.api.types import is_datetime64tz_dtype
404 >>> is_datetime64tz_dtype(object)
405 False
406 >>> is_datetime64tz_dtype([1, 2, 3])
407 False
408 >>> is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3])) # tz-naive
409 False
410 >>> is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern"))
411 True
412
413 >>> from pandas import DatetimeTZDtype
414 >>> dtype = DatetimeTZDtype("ns", tz="US/Eastern")
415 >>> s = pd.Series([], dtype=dtype)
416 >>> is_datetime64tz_dtype(dtype)
417 True
418 >>> is_datetime64tz_dtype(s)
419 True
420 """
421 # GH#52607
422 warnings.warn(
423 "is_datetime64tz_dtype is deprecated and will be removed in a future "
424 "version. Check `isinstance(dtype, pd.DatetimeTZDtype)` instead.",
425 Pandas4Warning,
426 stacklevel=2,
427 )
428 if isinstance(arr_or_dtype, DatetimeTZDtype):
429 # GH#33400 fastpath for dtype object
430 # GH 34986
431 return True
432
433 if arr_or_dtype is None:
434 return False
435 return DatetimeTZDtype.is_dtype(arr_or_dtype)
436
437
438@set_module("pandas.api.types")
439def is_timedelta64_dtype(arr_or_dtype) -> bool:
440 """
441 Check whether an array-like or dtype is of the timedelta64 dtype.
442
443 This function checks if the provided array-like object or dtype
444 corresponds to a timedelta64 dtype, which is used to represent
445 differences between two datetime values.
446
447 Parameters
448 ----------
449 arr_or_dtype : array-like or dtype
450 The array-like or dtype to check.
451
452 Returns
453 -------
454 boolean
455 Whether or not the array-like or dtype is of the timedelta64 dtype.
456
457 See Also
458 --------
459 api.types.is_timedelta64_ns_dtype : Check whether the provided array or dtype is
460 of the timedelta64[ns] dtype.
461 api.types.is_period_dtype : Check whether an array-like or dtype is of the
462 Period dtype.
463
464 Examples
465 --------
466 >>> from pandas.api.types import is_timedelta64_dtype
467 >>> is_timedelta64_dtype(object)
468 False
469 >>> is_timedelta64_dtype(np.timedelta64)
470 True
471 >>> is_timedelta64_dtype([1, 2, 3])
472 False
473 >>> is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]"))
474 True
475 >>> is_timedelta64_dtype("0 days")
476 False
477 """
478 if isinstance(arr_or_dtype, np.dtype):
479 # GH#33400 fastpath for dtype object
480 return arr_or_dtype.kind == "m"
481
482 return _is_dtype_type(arr_or_dtype, classes(np.timedelta64))
483
484
485@set_module("pandas.api.types")
486def is_period_dtype(arr_or_dtype) -> bool:
487 """
488 Check whether an array-like or dtype is of the Period dtype.
489
490 .. deprecated:: 2.2.0
491 Use isinstance(dtype, pd.PeriodDtype) instead.
492
493 Parameters
494 ----------
495 arr_or_dtype : array-like or dtype
496 The array-like or dtype to check.
497
498 Returns
499 -------
500 boolean
501 Whether or not the array-like or dtype is of the Period dtype.
502
503 See Also
504 --------
505 api.types.is_timedelta64_ns_dtype : Check whether the provided array or dtype is
506 of the timedelta64[ns] dtype.
507 api.types.is_timedelta64_dtype: Check whether an array-like or dtype
508 is of the timedelta64 dtype.
509
510 Examples
511 --------
512 >>> from pandas.api.types import is_period_dtype
513 >>> is_period_dtype(object)
514 False
515 >>> is_period_dtype(pd.PeriodDtype(freq="D"))
516 True
517 >>> is_period_dtype([1, 2, 3])
518 False
519 >>> is_period_dtype(pd.Period("2017-01-01"))
520 False
521 >>> is_period_dtype(pd.PeriodIndex([], freq="Y"))
522 True
523 """
524 warnings.warn(
525 "is_period_dtype is deprecated and will be removed in a future version. "
526 "Use `isinstance(dtype, pd.PeriodDtype)` instead",
527 Pandas4Warning,
528 stacklevel=2,
529 )
530 if isinstance(arr_or_dtype, ExtensionDtype):
531 # GH#33400 fastpath for dtype object
532 return arr_or_dtype.type is Period
533
534 if arr_or_dtype is None:
535 return False
536 return PeriodDtype.is_dtype(arr_or_dtype)
537
538
539@set_module("pandas.api.types")
540def is_interval_dtype(arr_or_dtype) -> bool:
541 """
542 Check whether an array-like or dtype is of the Interval dtype.
543
544 .. deprecated:: 2.2.0
545 Use isinstance(dtype, pd.IntervalDtype) instead.
546
547 Parameters
548 ----------
549 arr_or_dtype : array-like or dtype
550 The array-like or dtype to check.
551
552 Returns
553 -------
554 boolean
555 Whether or not the array-like or dtype is of the Interval dtype.
556
557 See Also
558 --------
559 api.types.is_object_dtype : Check whether an array-like or dtype is of the
560 object dtype.
561 api.types.is_numeric_dtype : Check whether the provided array or dtype is
562 of a numeric dtype.
563 api.types.is_categorical_dtype : Check whether an array-like or dtype is of
564 the Categorical dtype.
565
566 Examples
567 --------
568 >>> from pandas.api.types import is_interval_dtype
569 >>> is_interval_dtype(object)
570 False
571 >>> is_interval_dtype(pd.IntervalDtype())
572 True
573 >>> is_interval_dtype([1, 2, 3])
574 False
575 >>>
576 >>> interval = pd.Interval(1, 2, closed="right")
577 >>> is_interval_dtype(interval)
578 False
579 >>> is_interval_dtype(pd.IntervalIndex([interval]))
580 True
581 """
582 # GH#52607
583 warnings.warn(
584 "is_interval_dtype is deprecated and will be removed in a future version. "
585 "Use `isinstance(dtype, pd.IntervalDtype)` instead",
586 Pandas4Warning,
587 stacklevel=2,
588 )
589 if isinstance(arr_or_dtype, ExtensionDtype):
590 # GH#33400 fastpath for dtype object
591 return arr_or_dtype.type is Interval
592
593 if arr_or_dtype is None:
594 return False
595 return IntervalDtype.is_dtype(arr_or_dtype)
596
597
598@set_module("pandas.api.types")
599def is_categorical_dtype(arr_or_dtype) -> bool:
600 """
601 Check whether an array-like or dtype is of the Categorical dtype.
602
603 .. deprecated:: 2.2.0
604 Use isinstance(dtype, pd.CategoricalDtype) instead.
605
606 Parameters
607 ----------
608 arr_or_dtype : array-like or dtype
609 The array-like or dtype to check.
610
611 Returns
612 -------
613 boolean
614 Whether or not the array-like or dtype is of the Categorical dtype.
615
616 See Also
617 --------
618 api.types.is_list_like: Check if the object is list-like.
619 api.types.is_complex_dtype: Check whether the provided array or
620 dtype is of a complex dtype.
621
622 Examples
623 --------
624 >>> from pandas.api.types import is_categorical_dtype
625 >>> from pandas import CategoricalDtype
626 >>> is_categorical_dtype(object)
627 False
628 >>> is_categorical_dtype(CategoricalDtype())
629 True
630 >>> is_categorical_dtype([1, 2, 3])
631 False
632 >>> is_categorical_dtype(pd.Categorical([1, 2, 3]))
633 True
634 >>> is_categorical_dtype(pd.CategoricalIndex([1, 2, 3]))
635 True
636 """
637 # GH#52527
638 warnings.warn(
639 "is_categorical_dtype is deprecated and will be removed in a future "
640 "version. Use isinstance(dtype, pd.CategoricalDtype) instead",
641 Pandas4Warning,
642 stacklevel=2,
643 )
644 if isinstance(arr_or_dtype, ExtensionDtype):
645 # GH#33400 fastpath for dtype object
646 return arr_or_dtype.name == "category"
647
648 if arr_or_dtype is None:
649 return False
650 return CategoricalDtype.is_dtype(arr_or_dtype)
651
652
653def is_string_or_object_np_dtype(dtype: np.dtype) -> bool:
654 """
655 Faster alternative to is_string_dtype, assumes we have an np.dtype object.
656 """
657 return dtype == object or dtype.kind in "SU"
658
659
660@set_module("pandas.api.types")
661def is_string_dtype(arr_or_dtype) -> bool:
662 """
663 Check whether the provided array or dtype is of the string dtype.
664
665 If an array is passed with an object dtype, the elements must be
666 inferred as strings.
667
668 Parameters
669 ----------
670 arr_or_dtype : array-like or dtype
671 The array or dtype to check.
672
673 Returns
674 -------
675 boolean
676 Whether or not the array or dtype is of the string dtype.
677
678 See Also
679 --------
680 api.types.is_object_dtype : Check whether an array-like or dtype is of the
681 object dtype.
682
683 Examples
684 --------
685 >>> from pandas.api.types import is_string_dtype
686 >>> is_string_dtype(str)
687 True
688 >>> is_string_dtype(object)
689 True
690 >>> is_string_dtype(int)
691 False
692 >>> is_string_dtype(np.array(["a", "b"]))
693 True
694 >>> is_string_dtype(pd.Series([1, 2]))
695 False
696 >>> is_string_dtype(pd.Series([1, 2], dtype=object))
697 False
698 """
699 if hasattr(arr_or_dtype, "dtype") and _get_dtype(arr_or_dtype).kind == "O":
700 return is_all_strings(arr_or_dtype)
701
702 def condition(dtype) -> bool:
703 if is_string_or_object_np_dtype(dtype):
704 return True
705 try:
706 return dtype == "string"
707 except TypeError:
708 return False
709
710 return _is_dtype(arr_or_dtype, condition)
711
712
713@set_module("pandas.api.types")
714def is_dtype_equal(source, target) -> bool:
715 """
716 Check if two dtypes are equal.
717
718 This function compares two dtype specifications, handling both NumPy
719 dtypes and pandas ExtensionDtypes. String representations of dtypes
720 are also supported and will be resolved before comparison.
721
722 Parameters
723 ----------
724 source : type or str
725 The first dtype to compare.
726 target : type or str
727 The second dtype to compare.
728
729 Returns
730 -------
731 boolean
732 Whether or not the two dtypes are equal.
733
734 See Also
735 --------
736 api.types.is_categorical_dtype : Check whether the provided array or dtype
737 is of the Categorical dtype.
738 api.types.is_string_dtype : Check whether the provided array or dtype
739 is of the string dtype.
740 api.types.is_object_dtype : Check whether an array-like or dtype is of the
741 object dtype.
742
743 Examples
744 --------
745 >>> from pandas.api.types import is_dtype_equal
746 >>> is_dtype_equal(int, float)
747 False
748 >>> is_dtype_equal("int", int)
749 True
750 >>> is_dtype_equal(object, "category")
751 False
752 >>> from pandas.api.types import CategoricalDtype
753 >>> is_dtype_equal(CategoricalDtype(), "category")
754 True
755 >>> from pandas.api.types import DatetimeTZDtype
756 >>> is_dtype_equal(DatetimeTZDtype(tz="UTC"), "datetime64")
757 False
758 """
759 if isinstance(target, str):
760 if not isinstance(source, str):
761 # GH#38516 ensure we get the same behavior from
762 # is_dtype_equal(CDT, "category") and CDT == "category"
763 try:
764 src = _get_dtype(source)
765 if isinstance(src, ExtensionDtype):
766 return src == target
767 except (TypeError, AttributeError, ImportError):
768 return False
769 elif isinstance(source, str):
770 return is_dtype_equal(target, source)
771
772 try:
773 source = _get_dtype(source)
774 target = _get_dtype(target)
775 return source == target
776 except (TypeError, AttributeError, ImportError):
777 # invalid comparison
778 # object == category will hit this
779 return False
780
781
782@set_module("pandas.api.types")
783def is_integer_dtype(arr_or_dtype) -> bool:
784 """
785 Check whether the provided array or dtype is of an integer dtype.
786
787 Unlike in `is_any_int_dtype`, timedelta64 instances will return False.
788
789 The nullable Integer dtypes (e.g. pandas.Int64Dtype) are also considered
790 as integer by this function.
791
792 Parameters
793 ----------
794 arr_or_dtype : array-like or dtype
795 The array or dtype to check.
796
797 Returns
798 -------
799 boolean
800 Whether or not the array or dtype is of an integer dtype and
801 not an instance of timedelta64.
802
803 See Also
804 --------
805 api.types.is_integer : Return True if given object is integer.
806 api.types.is_numeric_dtype : Check whether the provided array or dtype is of a
807 numeric dtype.
808 api.types.is_float_dtype : Check whether the provided array or dtype is of a
809 float dtype.
810 Int64Dtype : An ExtensionDtype for Int64Dtype integer data.
811
812 Examples
813 --------
814 >>> from pandas.api.types import is_integer_dtype
815 >>> is_integer_dtype(str)
816 False
817 >>> is_integer_dtype(int)
818 True
819 >>> is_integer_dtype(float)
820 False
821 >>> is_integer_dtype(np.uint64)
822 True
823 >>> is_integer_dtype("int8")
824 True
825 >>> is_integer_dtype("Int8")
826 True
827 >>> is_integer_dtype(pd.Int8Dtype)
828 True
829 >>> is_integer_dtype(np.datetime64)
830 False
831 >>> is_integer_dtype(np.timedelta64)
832 False
833 >>> is_integer_dtype(np.array(["a", "b"]))
834 False
835 >>> is_integer_dtype(pd.Series([1, 2]))
836 True
837 >>> is_integer_dtype(np.array([], dtype="m8[ns]"))
838 False
839 >>> is_integer_dtype(pd.Index([1, 2.0])) # float
840 False
841 """
842 return _is_dtype_type(
843 arr_or_dtype, _classes_and_not_datetimelike(np.integer)
844 ) or _is_dtype(
845 arr_or_dtype, lambda typ: isinstance(typ, ExtensionDtype) and typ.kind in "iu"
846 )
847
848
849@set_module("pandas.api.types")
850def is_signed_integer_dtype(arr_or_dtype) -> bool:
851 """
852 Check whether the provided array or dtype is of a signed integer dtype.
853
854 Unlike in `is_any_int_dtype`, timedelta64 instances will return False.
855
856 The nullable Integer dtypes (e.g. pandas.Int64Dtype) are also considered
857 as integer by this function.
858
859 Parameters
860 ----------
861 arr_or_dtype : array-like or dtype
862 The array or dtype to check.
863
864 Returns
865 -------
866 boolean
867 Whether or not the array or dtype is of a signed integer dtype
868 and not an instance of timedelta64.
869
870 See Also
871 --------
872 api.types.is_integer_dtype: Check whether the provided array or dtype
873 is of an integer dtype.
874 api.types.is_numeric_dtype: Check whether the provided array or dtype
875 is of a numeric dtype.
876 api.types.is_unsigned_integer_dtype: Check whether the provided array
877 or dtype is of an unsigned integer dtype.
878
879 Examples
880 --------
881 >>> from pandas.api.types import is_signed_integer_dtype
882 >>> is_signed_integer_dtype(str)
883 False
884 >>> is_signed_integer_dtype(int)
885 True
886 >>> is_signed_integer_dtype(float)
887 False
888 >>> is_signed_integer_dtype(np.uint64) # unsigned
889 False
890 >>> is_signed_integer_dtype("int8")
891 True
892 >>> is_signed_integer_dtype("Int8")
893 True
894 >>> is_signed_integer_dtype(pd.Int8Dtype)
895 True
896 >>> is_signed_integer_dtype(np.datetime64)
897 False
898 >>> is_signed_integer_dtype(np.timedelta64)
899 False
900 >>> is_signed_integer_dtype(np.array(["a", "b"]))
901 False
902 >>> is_signed_integer_dtype(pd.Series([1, 2]))
903 True
904 >>> is_signed_integer_dtype(np.array([], dtype="m8[ns]"))
905 False
906 >>> is_signed_integer_dtype(pd.Index([1, 2.0])) # float
907 False
908 >>> is_signed_integer_dtype(np.array([1, 2], dtype=np.uint32)) # unsigned
909 False
910 """
911 return _is_dtype_type(
912 arr_or_dtype, _classes_and_not_datetimelike(np.signedinteger)
913 ) or _is_dtype(
914 arr_or_dtype, lambda typ: isinstance(typ, ExtensionDtype) and typ.kind == "i"
915 )
916
917
918@set_module("pandas.api.types")
919def is_unsigned_integer_dtype(arr_or_dtype) -> bool:
920 """
921 Check whether the provided array or dtype is of an unsigned integer dtype.
922
923 The nullable Integer dtypes (e.g. pandas.UInt64Dtype) are also
924 considered as integer by this function.
925
926 Parameters
927 ----------
928 arr_or_dtype : array-like or dtype
929 The array or dtype to check.
930
931 Returns
932 -------
933 boolean
934 Whether or not the array or dtype is of an unsigned integer dtype.
935
936 See Also
937 --------
938 api.types.is_signed_integer_dtype : Check whether the provided array
939 or dtype is of a signed integer dtype.
940 api.types.is_integer_dtype : Check whether the provided array or dtype
941 is of an integer dtype.
942 api.types.is_numeric_dtype : Check whether the provided array or dtype
943 is of a numeric dtype.
944
945 Examples
946 --------
947 >>> from pandas.api.types import is_unsigned_integer_dtype
948 >>> is_unsigned_integer_dtype(str)
949 False
950 >>> is_unsigned_integer_dtype(int) # signed
951 False
952 >>> is_unsigned_integer_dtype(float)
953 False
954 >>> is_unsigned_integer_dtype(np.uint64)
955 True
956 >>> is_unsigned_integer_dtype("uint8")
957 True
958 >>> is_unsigned_integer_dtype("UInt8")
959 True
960 >>> is_unsigned_integer_dtype(pd.UInt8Dtype)
961 True
962 >>> is_unsigned_integer_dtype(np.array(["a", "b"]))
963 False
964 >>> is_unsigned_integer_dtype(pd.Series([1, 2])) # signed
965 False
966 >>> is_unsigned_integer_dtype(pd.Index([1, 2.0])) # float
967 False
968 >>> is_unsigned_integer_dtype(np.array([1, 2], dtype=np.uint32))
969 True
970 """
971 return _is_dtype_type(
972 arr_or_dtype, _classes_and_not_datetimelike(np.unsignedinteger)
973 ) or _is_dtype(
974 arr_or_dtype, lambda typ: isinstance(typ, ExtensionDtype) and typ.kind == "u"
975 )
976
977
978@set_module("pandas.api.types")
979def is_int64_dtype(arr_or_dtype) -> bool:
980 """
981 Check whether the provided array or dtype is of the int64 dtype.
982
983 .. deprecated:: 2.1.0
984
985 is_int64_dtype is deprecated and will be removed in a future
986 version. Use dtype == np.int64 instead.
987
988 Parameters
989 ----------
990 arr_or_dtype : array-like or dtype
991 The array or dtype to check.
992
993 Returns
994 -------
995 boolean
996 Whether or not the array or dtype is of the int64 dtype.
997
998 See Also
999 --------
1000 api.types.is_float_dtype : Check whether the provided array or dtype is of a
1001 float dtype.
1002 api.types.is_bool_dtype : Check whether the provided array or dtype is of a
1003 boolean dtype.
1004 api.types.is_object_dtype : Check whether an array-like or dtype is of the
1005 object dtype.
1006 numpy.int64 : Numpy's 64-bit integer type.
1007
1008 Notes
1009 -----
1010 Depending on system architecture, the return value of `is_int64_dtype(
1011 int)` will be True if the OS uses 64-bit integers and False if the OS
1012 uses 32-bit integers.
1013
1014 Examples
1015 --------
1016 >>> from pandas.api.types import is_int64_dtype
1017 >>> is_int64_dtype(str) # doctest: +SKIP
1018 False
1019 >>> is_int64_dtype(np.int32) # doctest: +SKIP
1020 False
1021 >>> is_int64_dtype(np.int64) # doctest: +SKIP
1022 True
1023 >>> is_int64_dtype("int8") # doctest: +SKIP
1024 False
1025 >>> is_int64_dtype("Int8") # doctest: +SKIP
1026 False
1027 >>> is_int64_dtype(pd.Int64Dtype) # doctest: +SKIP
1028 True
1029 >>> is_int64_dtype(float) # doctest: +SKIP
1030 False
1031 >>> is_int64_dtype(np.uint64) # unsigned # doctest: +SKIP
1032 False
1033 >>> is_int64_dtype(np.array(["a", "b"])) # doctest: +SKIP
1034 False
1035 >>> is_int64_dtype(np.array([1, 2], dtype=np.int64)) # doctest: +SKIP
1036 True
1037 >>> is_int64_dtype(pd.Index([1, 2.0])) # float # doctest: +SKIP
1038 False
1039 >>> is_int64_dtype(np.array([1, 2], dtype=np.uint32)) # unsigned # doctest: +SKIP
1040 False
1041 """
1042 # GH#52564
1043 warnings.warn(
1044 "is_int64_dtype is deprecated and will be removed in a future "
1045 "version. Use dtype == np.int64 instead.",
1046 Pandas4Warning,
1047 stacklevel=2,
1048 )
1049 return _is_dtype_type(arr_or_dtype, classes(np.int64))
1050
1051
1052@set_module("pandas.api.types")
1053def is_datetime64_any_dtype(arr_or_dtype) -> bool:
1054 """
1055 Check whether the provided array or dtype is of the datetime64 dtype.
1056
1057 Unlike :func:`api.types.is_datetime64_dtype`, this function also
1058 considers timezone-aware dtypes such as ``DatetimeTZDtype`` to be
1059 datetime64 dtypes.
1060
1061 Parameters
1062 ----------
1063 arr_or_dtype : array-like or dtype
1064 The array or dtype to check.
1065
1066 Returns
1067 -------
1068 bool
1069 Whether or not the array or dtype is of the datetime64 dtype.
1070
1071 See Also
1072 --------
1073 api.types.is_datetime64_dtype : Check whether an array-like or dtype is of the
1074 datetime64 dtype.
1075 api.is_datetime64_ns_dtype : Check whether the provided array or dtype is of the
1076 datetime64[ns] dtype.
1077 api.is_datetime64tz_dtype : Check whether an array-like or dtype is of a
1078 DatetimeTZDtype dtype.
1079
1080 Examples
1081 --------
1082 >>> from pandas.api.types import is_datetime64_any_dtype
1083 >>> from pandas.api.types import DatetimeTZDtype
1084 >>> is_datetime64_any_dtype(str)
1085 False
1086 >>> is_datetime64_any_dtype(int)
1087 False
1088 >>> is_datetime64_any_dtype(np.datetime64) # can be tz-naive
1089 True
1090 >>> is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern"))
1091 True
1092 >>> is_datetime64_any_dtype(np.array(["a", "b"]))
1093 False
1094 >>> is_datetime64_any_dtype(np.array([1, 2]))
1095 False
1096 >>> is_datetime64_any_dtype(np.array([], dtype="datetime64[ns]"))
1097 True
1098 >>> is_datetime64_any_dtype(pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]"))
1099 True
1100 """
1101 if isinstance(arr_or_dtype, (np.dtype, ExtensionDtype)):
1102 # GH#33400 fastpath for dtype object
1103 return arr_or_dtype.kind == "M"
1104
1105 if arr_or_dtype is None:
1106 return False
1107
1108 try:
1109 tipo = _get_dtype(arr_or_dtype)
1110 except TypeError:
1111 return False
1112 return (
1113 lib.is_np_dtype(tipo, "M")
1114 or isinstance(tipo, DatetimeTZDtype)
1115 or (isinstance(tipo, ExtensionDtype) and tipo.kind == "M")
1116 )
1117
1118
1119@set_module("pandas.api.types")
1120def is_datetime64_ns_dtype(arr_or_dtype) -> bool:
1121 """
1122 Check whether the provided array or dtype is of the datetime64[ns] dtype.
1123
1124 This function is more restrictive than :func:`api.types.is_datetime64_dtype`
1125 because it requires the dtype to have nanosecond resolution specifically,
1126 including timezone-aware ``DatetimeTZDtype`` with nanosecond units.
1127
1128 Parameters
1129 ----------
1130 arr_or_dtype : array-like or dtype
1131 The array or dtype to check.
1132
1133 Returns
1134 -------
1135 bool
1136 Whether or not the array or dtype is of the datetime64[ns] dtype.
1137
1138 See Also
1139 --------
1140 api.types.is_datetime64_dtype: Check whether an array-like or
1141 dtype is of the datetime64 dtype.
1142 api.types.is_datetime64_any_dtype: Check whether the provided array or
1143 dtype is of the datetime64 dtype.
1144
1145 Examples
1146 --------
1147 >>> from pandas.api.types import is_datetime64_ns_dtype
1148 >>> from pandas.api.types import DatetimeTZDtype
1149 >>> is_datetime64_ns_dtype(str)
1150 False
1151 >>> is_datetime64_ns_dtype(int)
1152 False
1153 >>> is_datetime64_ns_dtype(np.datetime64) # no unit
1154 False
1155 >>> is_datetime64_ns_dtype(DatetimeTZDtype("ns", "US/Eastern"))
1156 True
1157 >>> is_datetime64_ns_dtype(np.array(["a", "b"]))
1158 False
1159 >>> is_datetime64_ns_dtype(np.array([1, 2]))
1160 False
1161 >>> is_datetime64_ns_dtype(np.array([], dtype="datetime64")) # no unit
1162 False
1163 >>> is_datetime64_ns_dtype(np.array([], dtype="datetime64[ps]")) # wrong unit
1164 False
1165 >>> is_datetime64_ns_dtype(pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]"))
1166 True
1167 """
1168 if arr_or_dtype is None:
1169 return False
1170 try:
1171 tipo = _get_dtype(arr_or_dtype)
1172 except TypeError:
1173 return False
1174 return tipo == DT64NS_DTYPE or (
1175 isinstance(tipo, DatetimeTZDtype) and tipo.unit == "ns"
1176 )
1177
1178
1179@set_module("pandas.api.types")
1180def is_timedelta64_ns_dtype(arr_or_dtype) -> bool:
1181 """
1182 Check whether the provided array or dtype is of the timedelta64[ns] dtype.
1183
1184 This is a very specific dtype, so generic ones like `np.timedelta64`
1185 will return False if passed into this function.
1186
1187 Parameters
1188 ----------
1189 arr_or_dtype : array-like or dtype
1190 The array or dtype to check.
1191
1192 Returns
1193 -------
1194 boolean
1195 Whether or not the array or dtype is of the timedelta64[ns] dtype.
1196
1197 See Also
1198 --------
1199 api.types.is_timedelta64_dtype: Check whether an array-like or dtype
1200 is of the timedelta64 dtype.
1201
1202 Examples
1203 --------
1204 >>> from pandas.api.types import is_timedelta64_ns_dtype
1205 >>> is_timedelta64_ns_dtype(np.dtype("m8[ns]"))
1206 True
1207 >>> is_timedelta64_ns_dtype(np.dtype("m8[ps]")) # Wrong frequency
1208 False
1209 >>> is_timedelta64_ns_dtype(np.array([1, 2], dtype="m8[ns]"))
1210 True
1211 >>> is_timedelta64_ns_dtype(np.array([1, 2], dtype="m8[ms]"))
1212 False
1213 """
1214 return _is_dtype(arr_or_dtype, lambda dtype: dtype == TD64NS_DTYPE)
1215
1216
1217# This exists to silence numpy deprecation warnings, see GH#29553
1218def is_numeric_v_string_like(a: ArrayLike, b) -> bool:
1219 """
1220 Check if we are comparing a string-like object to a numeric ndarray.
1221 NumPy doesn't like to compare such objects, especially numeric arrays
1222 and scalar string-likes.
1223
1224 Parameters
1225 ----------
1226 a : array-like, scalar
1227 The first object to check.
1228 b : array-like, scalar
1229 The second object to check.
1230
1231 Returns
1232 -------
1233 boolean
1234 Whether we return a comparing a string-like object to a numeric array.
1235
1236 Examples
1237 --------
1238 >>> is_numeric_v_string_like(np.array([1]), "foo")
1239 True
1240 >>> is_numeric_v_string_like(np.array([1, 2]), np.array(["foo"]))
1241 True
1242 >>> is_numeric_v_string_like(np.array(["foo"]), np.array([1, 2]))
1243 True
1244 >>> is_numeric_v_string_like(np.array([1]), np.array([2]))
1245 False
1246 >>> is_numeric_v_string_like(np.array(["foo"]), np.array(["foo"]))
1247 False
1248 """
1249 is_a_array = isinstance(a, np.ndarray)
1250 is_b_array = isinstance(b, np.ndarray)
1251
1252 is_a_numeric_array = is_a_array and a.dtype.kind in "uifcb"
1253 is_b_numeric_array = is_b_array and b.dtype.kind in "uifcb"
1254 is_a_string_array = is_a_array and a.dtype.kind in "SU"
1255 is_b_string_array = is_b_array and b.dtype.kind in "SU"
1256
1257 is_b_scalar_string_like = not is_b_array and isinstance(b, str)
1258
1259 return (
1260 (is_a_numeric_array and is_b_scalar_string_like)
1261 or (is_a_numeric_array and is_b_string_array)
1262 or (is_b_numeric_array and is_a_string_array)
1263 )
1264
1265
1266def needs_i8_conversion(dtype: DtypeObj | None) -> bool:
1267 """
1268 Check whether the dtype should be converted to int64.
1269
1270 Dtype "needs" such a conversion if the dtype is of a datetime-like dtype
1271
1272 Parameters
1273 ----------
1274 dtype : np.dtype, ExtensionDtype, or None
1275
1276 Returns
1277 -------
1278 boolean
1279 Whether or not the dtype should be converted to int64.
1280
1281 Examples
1282 --------
1283 >>> needs_i8_conversion(str)
1284 False
1285 >>> needs_i8_conversion(np.int64)
1286 False
1287 >>> needs_i8_conversion(np.datetime64)
1288 False
1289 >>> needs_i8_conversion(np.dtype(np.datetime64))
1290 True
1291 >>> needs_i8_conversion(np.array(["a", "b"]))
1292 False
1293 >>> needs_i8_conversion(pd.Series([1, 2]))
1294 False
1295 >>> needs_i8_conversion(pd.Series([], dtype="timedelta64[ns]"))
1296 False
1297 >>> needs_i8_conversion(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern"))
1298 False
1299 >>> needs_i8_conversion(pd.DatetimeIndex([1, 2, 3], tz="US/Eastern").dtype)
1300 True
1301 """
1302 if isinstance(dtype, np.dtype):
1303 return dtype.kind in "mM"
1304 return isinstance(dtype, (PeriodDtype, DatetimeTZDtype))
1305
1306
1307def is_arrow_temporal_dtype(dtype: DtypeObj | None) -> bool:
1308 """
1309 Check whether the dtype is an ArrowDtype holding timestamps or durations.
1310
1311 These are not covered by :func:`needs_i8_conversion`, so callers that gate
1312 datetime-like behavior on it need this check as well.
1313
1314 ``dtype.kind`` is not specific enough here: ``date32``/``date64`` also
1315 report kind "M" but are not backed by a DatetimeArray, so they are
1316 excluded.
1317
1318 Parameters
1319 ----------
1320 dtype : np.dtype, ExtensionDtype, or None
1321
1322 Returns
1323 -------
1324 boolean
1325 Whether or not the dtype is an ArrowDtype timestamp or duration.
1326 """
1327 if not isinstance(dtype, ArrowDtype):
1328 return False
1329 # ArrowDtype cannot be constructed without a supported pyarrow, so a plain
1330 # import is enough here; import_optional_dependency would re-run the
1331 # version check on every call and this is used in hot paths (GH#66445).
1332 import pyarrow as pa
1333
1334 pa_type = dtype.pyarrow_dtype
1335 return pa.types.is_timestamp(pa_type) or pa.types.is_duration(pa_type)
1336
1337
1338@set_module("pandas.api.types")
1339def is_numeric_dtype(arr_or_dtype) -> bool:
1340 """
1341 Check whether the provided array or dtype is of a numeric dtype.
1342
1343 Numeric dtypes include integer, float, complex, and boolean types.
1344 Datetime and timedelta dtypes are not considered numeric.
1345
1346 Parameters
1347 ----------
1348 arr_or_dtype : array-like or dtype
1349 The array or dtype to check.
1350
1351 Returns
1352 -------
1353 boolean
1354 Whether or not the array or dtype is of a numeric dtype.
1355
1356 See Also
1357 --------
1358 api.types.is_integer_dtype: Check whether the provided array or dtype
1359 is of an integer dtype.
1360 api.types.is_unsigned_integer_dtype: Check whether the provided array
1361 or dtype is of an unsigned integer dtype.
1362 api.types.is_signed_integer_dtype: Check whether the provided array
1363 or dtype is of a signed integer dtype.
1364
1365 Examples
1366 --------
1367 >>> from pandas.api.types import is_numeric_dtype
1368 >>> is_numeric_dtype(str)
1369 False
1370 >>> is_numeric_dtype(int)
1371 True
1372 >>> is_numeric_dtype(float)
1373 True
1374 >>> is_numeric_dtype(np.uint64)
1375 True
1376 >>> is_numeric_dtype(np.datetime64)
1377 False
1378 >>> is_numeric_dtype(np.timedelta64)
1379 False
1380 >>> is_numeric_dtype(np.array(["a", "b"]))
1381 False
1382 >>> is_numeric_dtype(pd.Series([1, 2]))
1383 True
1384 >>> is_numeric_dtype(pd.Index([1, 2.0]))
1385 True
1386 >>> is_numeric_dtype(np.array([], dtype="m8[ns]"))
1387 False
1388 """
1389 return _is_dtype_type(
1390 arr_or_dtype, _classes_and_not_datetimelike(np.number, np.bool_)
1391 ) or _is_dtype(
1392 arr_or_dtype, lambda typ: isinstance(typ, ExtensionDtype) and typ._is_numeric
1393 )
1394
1395
1396@set_module("pandas.api.types")
1397def is_any_real_numeric_dtype(arr_or_dtype) -> bool:
1398 """
1399 Check whether the provided array or dtype is of a real number dtype.
1400
1401 Real number dtypes include integer and float types but exclude complex
1402 and boolean dtypes. This is useful when operations require real-valued
1403 numeric input only.
1404
1405 Parameters
1406 ----------
1407 arr_or_dtype : array-like or dtype
1408 The array or dtype to check.
1409
1410 Returns
1411 -------
1412 boolean
1413 Whether or not the array or dtype is of a real number dtype.
1414
1415 See Also
1416 --------
1417 is_numeric_dtype : Check if a dtype is numeric.
1418 is_complex_dtype : Check if a dtype is complex.
1419 is_bool_dtype : Check if a dtype is boolean.
1420
1421 Examples
1422 --------
1423 >>> from pandas.api.types import is_any_real_numeric_dtype
1424 >>> is_any_real_numeric_dtype(int)
1425 True
1426 >>> is_any_real_numeric_dtype(float)
1427 True
1428 >>> is_any_real_numeric_dtype(object)
1429 False
1430 >>> is_any_real_numeric_dtype(str)
1431 False
1432 >>> is_any_real_numeric_dtype(complex(1, 2))
1433 False
1434 >>> is_any_real_numeric_dtype(bool)
1435 False
1436 """
1437 return (
1438 is_numeric_dtype(arr_or_dtype)
1439 and not is_complex_dtype(arr_or_dtype)
1440 and not is_bool_dtype(arr_or_dtype)
1441 )
1442
1443
1444@set_module("pandas.api.types")
1445def is_float_dtype(arr_or_dtype) -> bool:
1446 """
1447 Check whether the provided array or dtype is of a float dtype.
1448
1449 The function checks for floating-point data types, which represent real numbers
1450 that may have fractional components.
1451
1452 Parameters
1453 ----------
1454 arr_or_dtype : array-like or dtype
1455 The array or dtype to check.
1456
1457 Returns
1458 -------
1459 boolean
1460 Whether or not the array or dtype is of a float dtype.
1461
1462 See Also
1463 --------
1464 api.types.is_numeric_dtype : Check whether the provided array or dtype is of
1465 a numeric dtype.
1466 api.types.is_integer_dtype : Check whether the provided array or dtype is of
1467 an integer dtype.
1468 api.types.is_object_dtype : Check whether an array-like or dtype is of the
1469 object dtype.
1470
1471 Examples
1472 --------
1473 >>> from pandas.api.types import is_float_dtype
1474 >>> is_float_dtype(str)
1475 False
1476 >>> is_float_dtype(int)
1477 False
1478 >>> is_float_dtype(float)
1479 True
1480 >>> is_float_dtype(np.array(["a", "b"]))
1481 False
1482 >>> is_float_dtype(pd.Series([1, 2]))
1483 False
1484 >>> is_float_dtype(pd.Index([1, 2.0]))
1485 True
1486 """
1487 return _is_dtype_type(arr_or_dtype, classes(np.floating)) or _is_dtype(
1488 arr_or_dtype, lambda typ: isinstance(typ, ExtensionDtype) and typ.kind in "f"
1489 )
1490
1491
1492@set_module("pandas.api.types")
1493def is_bool_dtype(arr_or_dtype) -> bool:
1494 """
1495 Check whether the provided array or dtype is of a boolean dtype.
1496
1497 This function verifies whether a given object is a boolean data type. The input
1498 can be an array or a dtype object. Accepted array types include instances
1499 of ``np.array``, ``pd.Series``, ``pd.Index``, and similar array-like structures.
1500
1501 Parameters
1502 ----------
1503 arr_or_dtype : array-like or dtype
1504 The array or dtype to check.
1505
1506 Returns
1507 -------
1508 boolean
1509 Whether or not the array or dtype is of a boolean dtype.
1510
1511 See Also
1512 --------
1513 api.types.is_bool : Check if an object is a boolean.
1514
1515 Notes
1516 -----
1517 An ExtensionArray is considered boolean when the ``_is_boolean``
1518 attribute is set to True.
1519
1520 Examples
1521 --------
1522 >>> from pandas.api.types import is_bool_dtype
1523 >>> is_bool_dtype(str)
1524 False
1525 >>> is_bool_dtype(int)
1526 False
1527 >>> is_bool_dtype(bool)
1528 True
1529 >>> is_bool_dtype(np.bool_)
1530 True
1531 >>> is_bool_dtype(np.array(["a", "b"]))
1532 False
1533 >>> is_bool_dtype(pd.Series([1, 2]))
1534 False
1535 >>> is_bool_dtype(np.array([True, False]))
1536 True
1537 >>> is_bool_dtype(pd.Categorical([True, False]))
1538 True
1539 >>> is_bool_dtype(pd.arrays.SparseArray([True, False]))
1540 True
1541 """
1542 if arr_or_dtype is None:
1543 return False
1544 try:
1545 dtype = _get_dtype(arr_or_dtype)
1546 except (TypeError, ValueError):
1547 return False
1548
1549 if isinstance(dtype, CategoricalDtype):
1550 arr_or_dtype = dtype.categories
1551 # now we use the special definition for Index
1552
1553 if isinstance(arr_or_dtype, ABCIndex):
1554 # Allow Index[object] that is all-bools or Index["boolean"]
1555 if arr_or_dtype.inferred_type == "boolean":
1556 if not is_bool_dtype(arr_or_dtype.dtype):
1557 # GH#52680
1558 warnings.warn(
1559 "The behavior of is_bool_dtype with an object-dtype Index "
1560 "of bool objects is deprecated. In a future version, "
1561 "this will return False. Cast the Index to a bool dtype instead.",
1562 Pandas4Warning,
1563 stacklevel=2,
1564 )
1565 return True
1566 return False
1567 elif isinstance(dtype, ExtensionDtype):
1568 return getattr(dtype, "_is_boolean", False)
1569
1570 return issubclass(dtype.type, np.bool_)
1571
1572
1573def is_1d_only_ea_dtype(dtype: DtypeObj | None) -> bool:
1574 """
1575 Analogue to is_extension_array_dtype but excluding DatetimeTZDtype.
1576 """
1577 return isinstance(dtype, ExtensionDtype) and not dtype._supports_2d
1578
1579
1580@set_module("pandas.api.types")
1581def is_extension_array_dtype(arr_or_dtype) -> bool:
1582 """
1583 Check if an object is a pandas extension array type.
1584
1585 See the :ref:`Use Guide <extending.extension-types>` for more.
1586
1587 Parameters
1588 ----------
1589 arr_or_dtype : object
1590 For array-like input, the ``.dtype`` attribute will
1591 be extracted.
1592
1593 Returns
1594 -------
1595 bool
1596 Whether the `arr_or_dtype` is an extension array type.
1597
1598 See Also
1599 --------
1600 api.extensions.ExtensionArray : Abstract base class for pandas extension arrays.
1601
1602 Notes
1603 -----
1604 This checks whether an object implements the pandas extension
1605 array interface. In pandas, this includes:
1606
1607 * Categorical
1608 * Sparse
1609 * Interval
1610 * Period
1611 * DatetimeArray
1612 * TimedeltaArray
1613
1614 Third-party libraries may implement arrays or types satisfying
1615 this interface as well.
1616
1617 Examples
1618 --------
1619 >>> from pandas.api.types import is_extension_array_dtype
1620 >>> arr = pd.Categorical(["a", "b"])
1621 >>> is_extension_array_dtype(arr)
1622 True
1623 >>> is_extension_array_dtype(arr.dtype)
1624 True
1625
1626 >>> arr = np.array(["a", "b"])
1627 >>> is_extension_array_dtype(arr.dtype)
1628 False
1629 """
1630 dtype = getattr(arr_or_dtype, "dtype", arr_or_dtype)
1631 if isinstance(dtype, ExtensionDtype):
1632 return True
1633 elif isinstance(dtype, np.dtype):
1634 return False
1635 else:
1636 try:
1637 with warnings.catch_warnings():
1638 # pandas_dtype(..) can raise UserWarning for class input
1639 warnings.simplefilter("ignore", UserWarning)
1640 dtype = pandas_dtype(dtype)
1641 except (TypeError, ValueError):
1642 # np.dtype(..) can raise ValueError
1643 return False
1644 return isinstance(dtype, ExtensionDtype)
1645
1646
1647def is_ea_or_datetimelike_dtype(dtype: DtypeObj | None) -> bool:
1648 """
1649 Check for ExtensionDtype, datetime64 dtype, or timedelta64 dtype.
1650
1651 Notes
1652 -----
1653 Checks only for dtype objects, not dtype-castable strings or types.
1654 """
1655 return isinstance(dtype, ExtensionDtype) or (lib.is_np_dtype(dtype, "mM"))
1656
1657
1658@set_module("pandas.api.types")
1659def is_complex_dtype(arr_or_dtype) -> bool:
1660 """
1661 Check whether the provided array or dtype is of a complex dtype.
1662
1663 Complex dtypes represent numbers with both real and imaginary parts,
1664 such as ``np.complex64`` and ``np.complex128``.
1665
1666 Parameters
1667 ----------
1668 arr_or_dtype : array-like or dtype
1669 The array or dtype to check.
1670
1671 Returns
1672 -------
1673 boolean
1674 Whether or not the array or dtype is of a complex dtype.
1675
1676 See Also
1677 --------
1678 api.types.is_complex: Return True if given object is complex.
1679 api.types.is_numeric_dtype: Check whether the provided array or
1680 dtype is of a numeric dtype.
1681 api.types.is_integer_dtype: Check whether the provided array or
1682 dtype is of an integer dtype.
1683
1684 Examples
1685 --------
1686 >>> from pandas.api.types import is_complex_dtype
1687 >>> is_complex_dtype(str)
1688 False
1689 >>> is_complex_dtype(int)
1690 False
1691 >>> is_complex_dtype(np.complex128)
1692 True
1693 >>> is_complex_dtype(np.array(["a", "b"]))
1694 False
1695 >>> is_complex_dtype(pd.Series([1, 2]))
1696 False
1697 >>> is_complex_dtype(np.array([1 + 1j, 5]))
1698 True
1699 """
1700 return _is_dtype_type(arr_or_dtype, classes(np.complexfloating))
1701
1702
1703def _is_dtype(arr_or_dtype, condition) -> bool:
1704 """
1705 Return true if the condition is satisfied for the arr_or_dtype.
1706
1707 Parameters
1708 ----------
1709 arr_or_dtype : array-like, str, np.dtype, or ExtensionArrayType
1710 The array-like or dtype object whose dtype we want to extract.
1711 condition : callable[Union[np.dtype, ExtensionDtype]]
1712
1713 Returns
1714 -------
1715 bool
1716
1717 """
1718 if arr_or_dtype is None:
1719 return False
1720 try:
1721 dtype = _get_dtype(arr_or_dtype)
1722 except (TypeError, ValueError):
1723 return False
1724 return condition(dtype)
1725
1726
1727def _get_dtype(arr_or_dtype) -> DtypeObj:
1728 """
1729 Get the dtype instance associated with an array
1730 or dtype object.
1731
1732 Parameters
1733 ----------
1734 arr_or_dtype : array-like or dtype
1735 The array-like or dtype object whose dtype we want to extract.
1736
1737 Returns
1738 -------
1739 obj_dtype : The extract dtype instance from the
1740 passed in array or dtype object.
1741
1742 Raises
1743 ------
1744 TypeError : The passed in object is None.
1745 """
1746 if arr_or_dtype is None:
1747 raise TypeError("Cannot deduce dtype from null object")
1748
1749 # fastpath
1750 if isinstance(arr_or_dtype, np.dtype):
1751 return arr_or_dtype
1752 elif isinstance(arr_or_dtype, type):
1753 return np.dtype(arr_or_dtype)
1754
1755 # if we have an array-like
1756 elif hasattr(arr_or_dtype, "dtype"):
1757 arr_or_dtype = arr_or_dtype.dtype
1758
1759 return pandas_dtype(arr_or_dtype)
1760
1761
1762def _is_dtype_type(arr_or_dtype, condition) -> bool:
1763 """
1764 Return true if the condition is satisfied for the arr_or_dtype.
1765
1766 Parameters
1767 ----------
1768 arr_or_dtype : array-like or dtype
1769 The array-like or dtype object whose dtype we want to extract.
1770 condition : callable[Union[np.dtype, ExtensionDtypeType]]
1771
1772 Returns
1773 -------
1774 bool : if the condition is satisfied for the arr_or_dtype
1775 """
1776 if arr_or_dtype is None:
1777 return condition(type(None))
1778
1779 # fastpath
1780 if isinstance(arr_or_dtype, np.dtype):
1781 return condition(arr_or_dtype.type)
1782 elif isinstance(arr_or_dtype, type):
1783 if issubclass(arr_or_dtype, ExtensionDtype):
1784 arr_or_dtype = arr_or_dtype.type
1785 return condition(np.dtype(arr_or_dtype).type)
1786
1787 # if we have an array-like
1788 if hasattr(arr_or_dtype, "dtype"):
1789 arr_or_dtype = arr_or_dtype.dtype
1790
1791 # we are not possibly a dtype
1792 elif is_list_like(arr_or_dtype):
1793 return condition(type(None))
1794
1795 try:
1796 tipo = pandas_dtype(arr_or_dtype).type
1797 except (TypeError, ValueError):
1798 if is_scalar(arr_or_dtype):
1799 return condition(type(None))
1800
1801 return False
1802
1803 return condition(tipo)
1804
1805
1806def validate_all_hashable(*args, error_name: str | None = None) -> None:
1807 """
1808 Return None if all args are hashable, else raise a TypeError.
1809
1810 Parameters
1811 ----------
1812 *args
1813 Arguments to validate.
1814 error_name : str, optional
1815 The name to use if error
1816
1817 Raises
1818 ------
1819 TypeError : If an argument is not hashable
1820
1821 Returns
1822 -------
1823 None
1824 """
1825 if not all(is_hashable(arg) for arg in args):
1826 if error_name:
1827 raise TypeError(f"{error_name} must be a hashable type")
1828 raise TypeError("All elements must be hashable")
1829
1830
1831@set_module("pandas.api.types")
1832def pandas_dtype(dtype) -> DtypeObj:
1833 """
1834 Convert input into a pandas only dtype object or a numpy dtype object.
1835
1836 This function first checks for pandas extension types registered in the
1837 dtype registry, then falls back to NumPy dtype resolution. It accepts
1838 strings, types, numpy dtypes, and pandas ExtensionDtype instances.
1839
1840 Parameters
1841 ----------
1842 dtype : object
1843 The object to be converted into a dtype.
1844
1845 Returns
1846 -------
1847 np.dtype or a pandas dtype
1848 The converted dtype, which can be either a numpy dtype or a pandas dtype.
1849
1850 Raises
1851 ------
1852 TypeError if not a dtype
1853
1854 See Also
1855 --------
1856 api.types.is_dtype : Return true if the condition is satisfied for the arr_or_dtype.
1857
1858 Examples
1859 --------
1860 >>> pd.api.types.pandas_dtype(int)
1861 dtype('int64')
1862 """
1863 # short-circuit
1864 if isinstance(dtype, np.ndarray):
1865 return dtype.dtype
1866 elif isinstance(dtype, (np.dtype, ExtensionDtype)):
1867 return dtype
1868
1869 # builtin aliases
1870 if dtype is str and using_string_dtype():
1871 from pandas.core.arrays.string_ import StringDtype
1872
1873 return StringDtype(na_value=np.nan)
1874
1875 # registered extension types
1876 result = registry.find(dtype)
1877 if result is not None:
1878 if isinstance(result, type):
1879 # GH 31356, GH 54592
1880 warnings.warn(
1881 f"Instantiating {result.__name__} without any arguments."
1882 f"Pass a {result.__name__} instance to silence this warning.",
1883 UserWarning,
1884 stacklevel=find_stack_level(),
1885 )
1886 result = result()
1887 return result
1888
1889 # try a numpy dtype
1890 # raise a consistent TypeError if failed
1891 try:
1892 with warnings.catch_warnings():
1893 # TODO: warnings.catch_warnings can be removed when numpy>2.3.0
1894 # is the minimum version
1895 # GH#51523 - Series.astype(np.integer) doesn't show
1896 # numpy deprecation warning of np.integer
1897 # Hence enabling DeprecationWarning
1898 warnings.simplefilter("always", DeprecationWarning)
1899 npdtype = np.dtype(dtype)
1900 except TypeError:
1901 raise
1902 except ValueError as err:
1903 raise TypeError(f"data type '{dtype}' not understood") from err
1904
1905 # Any invalid dtype (such as pd.Timestamp) should raise an error.
1906 # np.dtype(invalid_type).kind = 0 for such objects. However, this will
1907 # also catch some valid dtypes such as object, np.object_ and 'object'
1908 # which we safeguard against by catching them earlier and returning
1909 # np.dtype(valid_dtype) before this condition is evaluated.
1910 if is_hashable(dtype) and dtype in [
1911 object,
1912 np.object_,
1913 "object",
1914 "O",
1915 "object_",
1916 ]:
1917 # check hashability to avoid errors/DeprecationWarning when we get
1918 # here and `dtype` is an array
1919 return npdtype
1920 elif npdtype.kind == "O":
1921 raise TypeError(f"dtype '{dtype}' not understood")
1922
1923 return npdtype
1924
1925
1926def is_all_strings(value: ArrayLike) -> bool:
1927 """
1928 Check if this is an array of strings that we should try parsing.
1929
1930 Includes object-dtype ndarray containing all-strings, StringArray,
1931 and Categorical with all-string categories.
1932 Does not include numpy string dtypes.
1933 """
1934 dtype = value.dtype
1935
1936 if isinstance(dtype, np.dtype):
1937 if len(value) == 0:
1938 return dtype == np.dtype("object")
1939 else:
1940 return dtype == np.dtype("object") and lib.is_string_array(
1941 np.asarray(value), skipna=False
1942 )
1943 elif isinstance(dtype, CategoricalDtype):
1944 return dtype.categories.inferred_type == "string"
1945 return dtype == "string"
1946
1947
1948__all__ = [
1949 "DT64NS_DTYPE",
1950 "INT64_DTYPE",
1951 "TD64NS_DTYPE",
1952 "classes",
1953 "ensure_float64",
1954 "ensure_python_int",
1955 "ensure_str",
1956 "is_1d_only_ea_dtype",
1957 "is_all_strings",
1958 "is_any_real_numeric_dtype",
1959 "is_array_like",
1960 "is_bool",
1961 "is_bool_dtype",
1962 "is_categorical_dtype",
1963 "is_complex",
1964 "is_complex_dtype",
1965 "is_dataclass",
1966 "is_datetime64_any_dtype",
1967 "is_datetime64_dtype",
1968 "is_datetime64_ns_dtype",
1969 "is_datetime64tz_dtype",
1970 "is_decimal",
1971 "is_dict_like",
1972 "is_dtype_equal",
1973 "is_ea_or_datetimelike_dtype",
1974 "is_extension_array_dtype",
1975 "is_file_like",
1976 "is_float_dtype",
1977 "is_int64_dtype",
1978 "is_integer_dtype",
1979 "is_interval_dtype",
1980 "is_iterator",
1981 "is_named_tuple",
1982 "is_nested_list_like",
1983 "is_number",
1984 "is_numeric_dtype",
1985 "is_object_dtype",
1986 "is_period_dtype",
1987 "is_re",
1988 "is_re_compilable",
1989 "is_scipy_sparse",
1990 "is_sequence",
1991 "is_signed_integer_dtype",
1992 "is_sparse",
1993 "is_string_dtype",
1994 "is_string_or_object_np_dtype",
1995 "is_timedelta64_dtype",
1996 "is_timedelta64_ns_dtype",
1997 "is_unsigned_integer_dtype",
1998 "needs_i8_conversion",
1999 "pandas_dtype",
2000 "validate_all_hashable",
2001]