Skip to content

Commit 748be1b

Browse files
committed
REF (feedback): move maybe_box_datetimelike common.py -> dtypes/cast.py
2 parents bebb60c + 64a4df1 commit 748be1b

File tree

85 files changed

+1331
-1143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1331
-1143
lines changed

doc/source/user_guide/indexing.rst

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,19 +1594,16 @@ See :ref:`Advanced Indexing <advanced>` for usage of MultiIndexes.
15941594
Set operations on Index objects
15951595
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15961596

1597-
The two main operations are ``union (|)`` and ``intersection (&)``.
1598-
These can be directly called as instance methods or used via overloaded
1599-
operators. Difference is provided via the ``.difference()`` method.
1597+
The two main operations are ``union`` and ``intersection``.
1598+
Difference is provided via the ``.difference()`` method.
16001599

16011600
.. ipython:: python
16021601
16031602
a = pd.Index(['c', 'b', 'a'])
16041603
b = pd.Index(['c', 'e', 'd'])
1605-
a | b
1606-
a & b
16071604
a.difference(b)
16081605
1609-
Also available is the ``symmetric_difference (^)`` operation, which returns elements
1606+
Also available is the ``symmetric_difference`` operation, which returns elements
16101607
that appear in either ``idx1`` or ``idx2``, but not in both. This is
16111608
equivalent to the Index created by ``idx1.difference(idx2).union(idx2.difference(idx1))``,
16121609
with duplicates dropped.
@@ -1616,7 +1613,6 @@ with duplicates dropped.
16161613
idx1 = pd.Index([1, 2, 3, 4])
16171614
idx2 = pd.Index([2, 3, 4, 5])
16181615
idx1.symmetric_difference(idx2)
1619-
idx1 ^ idx2
16201616
16211617
.. note::
16221618

@@ -1631,7 +1627,7 @@ integer values are converted to float
16311627
16321628
idx1 = pd.Index([0, 1, 2])
16331629
idx2 = pd.Index([0.5, 1.5])
1634-
idx1 | idx2
1630+
idx1.union(idx2)
16351631
16361632
.. _indexing.missing:
16371633

doc/source/user_guide/missing_data.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ at the new values.
466466
ser = pd.Series(np.sort(np.random.uniform(size=100)))
467467
468468
# interpolate at new_index
469-
new_index = ser.index | pd.Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75])
469+
new_index = ser.index.union(pd.Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75]))
470470
interp_s = ser.reindex(new_index).interpolate(method="pchip")
471471
interp_s[49:51]
472472

doc/source/whatsnew/v1.2.0.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ Other enhancements
228228
- :class:`Rolling` now supports the ``closed`` argument for fixed windows (:issue:`34315`)
229229
- :class:`DatetimeIndex` and :class:`Series` with ``datetime64`` or ``datetime64tz`` dtypes now support ``std`` (:issue:`37436`)
230230
- :class:`Window` now supports all Scipy window types in ``win_type`` with flexible keyword argument support (:issue:`34556`)
231+
- :meth:`testing.assert_index_equal` now has a ``check_order`` parameter that allows indexes to be checked in an order-insensitive manner (:issue:`37478`)
231232

232233
.. _whatsnew_120.api_breaking.python:
233234

@@ -338,6 +339,8 @@ Deprecations
338339
- Deprecated slice-indexing on timezone-aware :class:`DatetimeIndex` with naive ``datetime`` objects, to match scalar indexing behavior (:issue:`36148`)
339340
- :meth:`Index.ravel` returning a ``np.ndarray`` is deprecated, in the future this will return a view on the same index (:issue:`19956`)
340341
- Deprecate use of strings denoting units with 'M', 'Y' or 'y' in :func:`~pandas.to_timedelta` (:issue:`36666`)
342+
- :class:`Index` methods ``&``, ``|``, and ``^`` behaving as the set operations :meth:`Index.intersection`, :meth:`Index.union`, and :meth:`Index.symmetric_difference`, respectively, are deprecated and in the future will behave as pointwise boolean operations matching :class:`Series` behavior. Use the named set methods instead (:issue:`36758`)
343+
- :meth:`Categorical.is_dtype_equal` and :meth:`CategoricalIndex.is_dtype_equal` are deprecated, will be removed in a future version (:issue:`37545`)
341344

342345
.. ---------------------------------------------------------------------------
343346
@@ -531,7 +534,7 @@ Reshaping
531534
- Bug in :meth:`Series.transform` would give incorrect results or raise when the argument ``func`` was dictionary (:issue:`35811`)
532535
- Bug in :meth:`DataFrame.pivot` did not preserve :class:`MultiIndex` level names for columns when rows and columns both multiindexed (:issue:`36360`)
533536
- Bug in :func:`join` returned a non deterministic level-order for the resulting :class:`MultiIndex` (:issue:`36910`)
534-
-
537+
- Bug in :meth:`DataFrame.combine_first()` caused wrong alignment with dtype ``string`` and one level of ``MultiIndex`` containing only ``NA`` (:issue:`37591`)
535538

536539
Sparse
537540
^^^^^^
@@ -546,6 +549,7 @@ ExtensionArray
546549
- Fixed bug where ``astype()`` with equal dtype and ``copy=False`` would return a new object (:issue:`284881`)
547550
- Fixed bug when applying a NumPy ufunc with multiple outputs to a :class:`pandas.arrays.IntegerArray` returning None (:issue:`36913`)
548551
- Fixed an inconsistency in :class:`PeriodArray`'s ``__init__`` signature to those of :class:`DatetimeArray` and :class:`TimedeltaArray` (:issue:`37289`)
552+
- Bug in :meth:`Series.replace` did not preserve ``dtype`` of original :class:`Series` (:issue:`33484`)
549553
- Reductions for :class:`BooleanArray`, :class:`Categorical`, :class:`DatetimeArray`, :class:`FloatingArray`, :class:`IntegerArray`, :class:`PeriodArray`, :class:`TimedeltaArray`, and :class:`PandasArray` are now keyword-only methods (:issue:`37541`)
550554

551555
Other

pandas/_config/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class option_context(ContextDecorator):
392392
"""
393393

394394
def __init__(self, *args):
395-
if not (len(args) % 2 == 0 and len(args) >= 2):
395+
if len(args) % 2 != 0 or len(args) < 2:
396396
raise ValueError(
397397
"Need to invoke as option_context(pat, val, [(pat, val), ...])."
398398
)
@@ -648,7 +648,7 @@ def _build_option_description(k: str) -> str:
648648
s += f"\n [default: {o.defval}] [currently: {_get_option(k, True)}]"
649649

650650
if d:
651-
rkey = d.rkey if d.rkey else ""
651+
rkey = d.rkey or ""
652652
s += "\n (Deprecated"
653653
s += f", use `{rkey}` instead."
654654
s += ")"

pandas/_config/localization.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ def _valid_locales(locales, normalize):
9999

100100

101101
def _default_locale_getter():
102-
raw_locales = subprocess.check_output(["locale -a"], shell=True)
103-
return raw_locales
102+
return subprocess.check_output(["locale -a"], shell=True)
104103

105104

106105
def get_locales(prefix=None, normalize=True, locale_getter=_default_locale_getter):

pandas/_testing.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ def assert_index_equal(
667667
check_less_precise: Union[bool, int] = no_default,
668668
check_exact: bool = True,
669669
check_categorical: bool = True,
670+
check_order: bool = True,
670671
rtol: float = 1.0e-5,
671672
atol: float = 1.0e-8,
672673
obj: str = "Index",
@@ -696,6 +697,12 @@ def assert_index_equal(
696697
Whether to compare number exactly.
697698
check_categorical : bool, default True
698699
Whether to compare internal Categorical exactly.
700+
check_order : bool, default True
701+
Whether to compare the order of index entries as well as their values.
702+
If True, both indexes must contain the same elements, in the same order.
703+
If False, both indexes must contain the same elements, but in any order.
704+
705+
.. versionadded:: 1.2.0
699706
rtol : float, default 1e-5
700707
Relative tolerance. Only used when check_exact is False.
701708
@@ -729,8 +736,7 @@ def _get_ilevel_values(index, level):
729736
unique = index.levels[level]
730737
level_codes = index.codes[level]
731738
filled = take_1d(unique._values, level_codes, fill_value=unique._na_value)
732-
values = unique._shallow_copy(filled, name=index.names[level])
733-
return values
739+
return unique._shallow_copy(filled, name=index.names[level])
734740

735741
if check_less_precise is not no_default:
736742
warnings.warn(
@@ -762,6 +768,11 @@ def _get_ilevel_values(index, level):
762768
msg3 = f"{len(right)}, {right}"
763769
raise_assert_detail(obj, msg1, msg2, msg3)
764770

771+
# If order doesn't matter then sort the index entries
772+
if not check_order:
773+
left = left.sort_values()
774+
right = right.sort_values()
775+
765776
# MultiIndex special comparison for little-friendly error messages
766777
if left.nlevels > 1:
767778
left = cast(MultiIndex, left)
@@ -1582,9 +1593,6 @@ def assert_frame_equal(
15821593
obj, f"{obj} shape mismatch", f"{repr(left.shape)}", f"{repr(right.shape)}"
15831594
)
15841595

1585-
if check_like:
1586-
left, right = left.reindex_like(right), right
1587-
15881596
if check_flags:
15891597
assert left.flags == right.flags, f"{repr(left.flags)} != {repr(right.flags)}"
15901598

@@ -1596,6 +1604,7 @@ def assert_frame_equal(
15961604
check_names=check_names,
15971605
check_exact=check_exact,
15981606
check_categorical=check_categorical,
1607+
check_order=not check_like,
15991608
rtol=rtol,
16001609
atol=atol,
16011610
obj=f"{obj}.index",
@@ -1609,11 +1618,15 @@ def assert_frame_equal(
16091618
check_names=check_names,
16101619
check_exact=check_exact,
16111620
check_categorical=check_categorical,
1621+
check_order=not check_like,
16121622
rtol=rtol,
16131623
atol=atol,
16141624
obj=f"{obj}.columns",
16151625
)
16161626

1627+
if check_like:
1628+
left, right = left.reindex_like(right), right
1629+
16171630
# compare by blocks
16181631
if by_blocks:
16191632
rblocks = right._to_dict_of_blocks()
@@ -1871,8 +1884,7 @@ def makeTimedeltaIndex(k=10, freq="D", name=None, **kwargs):
18711884

18721885
def makePeriodIndex(k=10, name=None, **kwargs):
18731886
dt = datetime(2000, 1, 1)
1874-
dr = pd.period_range(start=dt, periods=k, freq="B", name=name, **kwargs)
1875-
return dr
1887+
return pd.period_range(start=dt, periods=k, freq="B", name=name, **kwargs)
18761888

18771889

18781890
def makeMultiIndex(k=10, names=None, **kwargs):
@@ -2511,9 +2523,12 @@ def network(
25112523

25122524
@wraps(t)
25132525
def wrapper(*args, **kwargs):
2514-
if check_before_test and not raise_on_error:
2515-
if not can_connect(url, error_classes):
2516-
skip()
2526+
if (
2527+
check_before_test
2528+
and not raise_on_error
2529+
and not can_connect(url, error_classes)
2530+
):
2531+
skip()
25172532
try:
25182533
return t(*args, **kwargs)
25192534
except Exception as err:
@@ -2928,8 +2943,7 @@ def convert_rows_list_to_csv_str(rows_list: List[str]):
29282943
Expected output of to_csv() in current OS.
29292944
"""
29302945
sep = os.linesep
2931-
expected = sep.join(rows_list) + sep
2932-
return expected
2946+
return sep.join(rows_list) + sep
29332947

29342948

29352949
def external_error_raised(expected_exception: Type[Exception]) -> ContextManager:

pandas/_version.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ def get_keywords():
2222
# get_keywords().
2323
git_refnames = "$Format:%d$"
2424
git_full = "$Format:%H$"
25-
keywords = {"refnames": git_refnames, "full": git_full}
26-
return keywords
25+
return {"refnames": git_refnames, "full": git_full}
2726

2827

2928
class VersioneerConfig:
@@ -121,17 +120,16 @@ def git_get_keywords(versionfile_abs):
121120
# _version.py.
122121
keywords = {}
123122
try:
124-
f = open(versionfile_abs)
125-
for line in f.readlines():
126-
if line.strip().startswith("git_refnames ="):
127-
mo = re.search(r'=\s*"(.*)"', line)
128-
if mo:
129-
keywords["refnames"] = mo.group(1)
130-
if line.strip().startswith("git_full ="):
131-
mo = re.search(r'=\s*"(.*)"', line)
132-
if mo:
133-
keywords["full"] = mo.group(1)
134-
f.close()
123+
with open(versionfile_abs) as fd:
124+
for line in fd.readlines():
125+
if line.strip().startswith("git_refnames ="):
126+
mo = re.search(r'=\s*"(.*)"', line)
127+
if mo:
128+
keywords["refnames"] = mo.group(1)
129+
if line.strip().startswith("git_full ="):
130+
mo = re.search(r'=\s*"(.*)"', line)
131+
if mo:
132+
keywords["full"] = mo.group(1)
135133
except OSError:
136134
pass
137135
return keywords
@@ -286,13 +284,11 @@ def render_pep440(pieces):
286284
if pieces["distance"] or pieces["dirty"]:
287285
rendered += plus_or_dot(pieces)
288286
rendered += f"{pieces['distance']:d}.g{pieces['short']}"
289-
if pieces["dirty"]:
290-
rendered += ".dirty"
291287
else:
292288
# exception #1
293289
rendered = f"0+untagged.{pieces['distance']:d}.g{pieces['short']}"
294-
if pieces["dirty"]:
295-
rendered += ".dirty"
290+
if pieces["dirty"]:
291+
rendered += ".dirty"
296292
return rendered
297293

298294

@@ -348,13 +344,11 @@ def render_pep440_old(pieces):
348344
rendered = pieces["closest-tag"]
349345
if pieces["distance"] or pieces["dirty"]:
350346
rendered += f".post{pieces['distance']:d}"
351-
if pieces["dirty"]:
352-
rendered += ".dev0"
353347
else:
354348
# exception #1
355349
rendered = f"0.post{pieces['distance']:d}"
356-
if pieces["dirty"]:
357-
rendered += ".dev0"
350+
if pieces["dirty"]:
351+
rendered += ".dev0"
358352
return rendered
359353

360354

pandas/compat/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def is_platform_windows() -> bool:
5050
bool
5151
True if the running platform is windows.
5252
"""
53-
return sys.platform == "win32" or sys.platform == "cygwin"
53+
return sys.platform in ["win32", "cygwin"]
5454

5555

5656
def is_platform_linux() -> bool:

pandas/conftest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,12 @@ def _create_multiindex():
386386
major_codes = np.array([0, 0, 1, 2, 3, 3])
387387
minor_codes = np.array([0, 1, 0, 1, 0, 1])
388388
index_names = ["first", "second"]
389-
mi = MultiIndex(
389+
return MultiIndex(
390390
levels=[major_axis, minor_axis],
391391
codes=[major_codes, minor_codes],
392392
names=index_names,
393393
verify_integrity=False,
394394
)
395-
return mi
396395

397396

398397
def _create_mi_with_dt64tz_level():

pandas/core/arrays/_mixins.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,24 @@ def _reduce(self, name: str, skipna: bool = True, **kwargs):
252252
else:
253253
msg = f"'{type(self).__name__}' does not implement reduction '{name}'"
254254
raise TypeError(msg)
255+
256+
# ------------------------------------------------------------------------
257+
258+
def __repr__(self) -> str:
259+
if self.ndim == 1:
260+
return super().__repr__()
261+
262+
from pandas.io.formats.printing import format_object_summary
263+
264+
# the short repr has no trailing newline, while the truncated
265+
# repr does. So we include a newline in our template, and strip
266+
# any trailing newlines from format_object_summary
267+
lines = [
268+
format_object_summary(x, self._formatter(), indent_for_name=False).rstrip(
269+
", \n"
270+
)
271+
for x in self
272+
]
273+
data = ",\n".join(lines)
274+
class_name = f"<{type(self).__name__}>"
275+
return f"{class_name}\n[\n{data}\n]\nShape: {self.shape}, dtype: {self.dtype}"

pandas/core/arrays/boolean.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,11 @@ def _arith_method(self, other, op):
664664
dtype = "bool"
665665
result = np.zeros(len(self._data), dtype=dtype)
666666
else:
667+
if op_name in {"pow", "rpow"} and isinstance(other, np.bool_):
668+
# Avoid DeprecationWarning: In future, it will be an error
669+
# for 'np.bool_' scalars to be interpreted as an index
670+
other = bool(other)
671+
667672
with np.errstate(all="ignore"):
668673
result = op(self._data, other)
669674

0 commit comments

Comments
 (0)