Skip to content

Commit 8fe9f69

Browse files
Merge remote-tracking branch 'upstream/master' into skip_if_no
2 parents 85b8c63 + cf25c5c commit 8fe9f69

File tree

17 files changed

+80
-23
lines changed

17 files changed

+80
-23
lines changed

.github/FUNDING.yml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
custom: https://pandas.pydata.org/donate.html

asv_bench/benchmarks/index_object.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def time_get_loc(self):
188188

189189
class IntervalIndexMethod:
190190
# GH 24813
191-
params = [10**3, 10**5, 10**7]
191+
params = [10**3, 10**5]
192192

193193
def setup(self, N):
194194
left = np.append(np.arange(N), np.array(0))

ci/deps/travis-36-cov.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ dependencies:
2020
# https://github.com/pydata/pandas-gbq/issues/271
2121
- google-cloud-bigquery<=1.11
2222
- psycopg2
23-
- pyarrow=0.9.0
23+
# pyarrow segfaults on load: https://github.com/pandas-dev/pandas/issues/26716
24+
# - pyarrow=0.9.0
2425
- pymysql
2526
- pytables
2627
- python-snappy

ci/deps/travis-36-doc.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ dependencies:
3333
- pytz
3434
- scipy
3535
- seaborn
36-
- sphinx
36+
# recursion error with sphinx 2.1.0. https://github.com/pandas-dev/pandas/issues/26723
37+
- sphinx==2.0.1
3738
- sqlalchemy
3839
- statsmodels
3940
- xarray

doc/source/whatsnew/v0.25.0.rst

+3
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ Performance Improvements
513513
- Improved performance of :meth:`IntervalIndex.intersection` (:issue:`24813`)
514514
- Improved performance of :meth:`read_csv` by faster concatenating date columns without extra conversion to string for integer/float zero and float ``NaN``; by faster checking the string for the possibility of being a date (:issue:`25754`)
515515
- Improved performance of :attr:`IntervalIndex.is_unique` by removing conversion to ``MultiIndex`` (:issue:`24813`)
516+
- Restored performance of :meth:`DatetimeIndex.__iter__` by re-enabling specialized code path (:issue:`26702`)
516517

517518
.. _whatsnew_0250.bug_fixes:
518519

@@ -539,13 +540,15 @@ Datetimelike
539540
- Bug in adding :class:`DateOffset` with nonzero month to :class:`DatetimeIndex` would raise ``ValueError`` (:issue:`26258`)
540541
- Bug in :func:`to_datetime` which raises unhandled ``OverflowError`` when called with mix of invalid dates and ``NaN`` values with ``format='%Y%m%d'`` and ``error='coerce'`` (:issue:`25512`)
541542
- Bug in :func:`to_datetime` which raises ``TypeError`` for ``format='%Y%m%d'`` when called for invalid integer dates with length >= 6 digits with ``errors='ignore'``
543+
- Bug when comparing a :class:`PeriodIndex` against a zero-dimensional numpy array (:issue:`26689`)
542544

543545
Timedelta
544546
^^^^^^^^^
545547

546548
- Bug in :func:`TimedeltaIndex.intersection` where for non-monotonic indices in some cases an empty ``Index`` was returned when in fact an intersection existed (:issue:`25913`)
547549
- Bug with comparisons between :class:`Timedelta` and ``NaT`` raising ``TypeError`` (:issue:`26039`)
548550
- Bug when adding or subtracting a :class:`BusinessHour` to a :class:`Timestamp` with the resulting time landing in a following or prior day respectively (:issue:`26381`)
551+
- Bug when comparing a :class:`TimedeltaIndex` against a zero-dimensional numpy array (:issue:`26689`)
549552

550553
Timezones
551554
^^^^^^^^^

environment.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@ dependencies:
1616
- cython>=0.28.2
1717

1818
# code checks
19+
- cpplint
1920
- flake8
2021
- flake8-comprehensions # used by flake8, linting of unnecessary comprehensions
2122
- flake8-rst>=0.6.0,<=0.7.0 # linting of code blocks in rst files
2223
- isort # check that imports are in the right order
2324
- mypy
2425
- pycodestyle # used by flake8
25-
- pip:
26-
- cpplint
2726

2827
# documentation
2928
- gitpython # obtain contributors from git for whatsnew

pandas/core/arrays/period.py

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import numpy as np
66

7+
from pandas._libs import lib
78
from pandas._libs.tslibs import (
89
NaT, NaTType, frequencies as libfrequencies, iNaT, period as libperiod)
910
from pandas._libs.tslibs.fields import isleapyear_arr
@@ -51,6 +52,7 @@ def _period_array_cmp(cls, op):
5152
def wrapper(self, other):
5253
op = getattr(self.asi8, opname)
5354

55+
other = lib.item_from_zerodim(other)
5456
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
5557
return NotImplemented
5658

pandas/core/arrays/timedeltas.py

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def _td_array_cmp(cls, op):
6262
nat_result = opname == '__ne__'
6363

6464
def wrapper(self, other):
65+
other = lib.item_from_zerodim(other)
6566
if isinstance(other, (ABCDataFrame, ABCSeries, ABCIndexClass)):
6667
return NotImplemented
6768

pandas/core/indexes/datetimes.py

+2
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ def _join_i8_wrapper(joinf, **kwargs):
243243
_is_numeric_dtype = False
244244
_infer_as_myclass = True
245245

246+
# Use faster implementation given we know we have DatetimeArrays
247+
__iter__ = DatetimeArray.__iter__
246248
# some things like freq inference make use of these attributes.
247249
_bool_ops = DatetimeArray._bool_ops
248250
_object_ops = DatetimeArray._object_ops

pandas/core/indexes/range.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,9 @@ def __contains__(self, key: Union[int, np.integer]) -> bool:
346346
@Appender(_index_shared_docs['get_loc'])
347347
def get_loc(self, key, method=None, tolerance=None):
348348
if is_integer(key) and method is None and tolerance is None:
349+
new_key = int(key)
349350
try:
350-
return self._range.index(key)
351+
return self._range.index(new_key)
351352
except ValueError:
352353
raise KeyError(key)
353354
return super().get_loc(key, method=method, tolerance=tolerance)
@@ -608,19 +609,15 @@ def __getitem__(self, key):
608609
"""
609610
Conserve RangeIndex type for scalar and slice keys.
610611
"""
611-
super_getitem = super().__getitem__
612-
613612
if is_scalar(key):
614613
if not lib.is_integer(key):
615614
raise IndexError("only integers, slices (`:`), "
616615
"ellipsis (`...`), numpy.newaxis (`None`) "
617616
"and integer or boolean "
618617
"arrays are valid indices")
619-
n = com.cast_scalar_indexer(key)
620-
if n != key:
621-
return super_getitem(key)
618+
new_key = int(key)
622619
try:
623-
return self._range[key]
620+
return self._range[new_key]
624621
except IndexError:
625622
raise IndexError("index {key} is out of bounds for axis 0 "
626623
"with size {size}".format(key=key,
@@ -630,7 +627,7 @@ def __getitem__(self, key):
630627
return self.from_range(new_range, name=self.name)
631628

632629
# fall back to Int64Index
633-
return super_getitem(key)
630+
return super().__getitem__(key)
634631

635632
def __floordiv__(self, other):
636633
if isinstance(other, (ABCSeries, ABCDataFrame)):

pandas/tests/arithmetic/test_datetime64.py

+12
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def assert_all(obj):
3737
# ------------------------------------------------------------------
3838
# Comparisons
3939

40+
4041
class TestDatetime64DataFrameComparison:
4142
@pytest.mark.parametrize('timestamps', [
4243
[pd.Timestamp('2012-01-01 13:00:00+00:00')] * 2,
@@ -338,6 +339,17 @@ def test_comparison_tzawareness_compat(self, op):
338339

339340
class TestDatetimeIndexComparisons:
340341

342+
# TODO: parametrize over box
343+
def test_compare_zerodim(self, tz_naive_fixture):
344+
# Test comparison with zero-dimensional array is unboxed
345+
tz = tz_naive_fixture
346+
dti = date_range('20130101', periods=3, tz=tz)
347+
348+
other = np.array(dti.to_numpy()[0])
349+
result = dti <= other
350+
expected = np.array([True, False, False])
351+
tm.assert_numpy_array_equal(result, expected)
352+
341353
# TODO: moved from tests.indexes.test_base; parametrize and de-duplicate
342354
@pytest.mark.parametrize("op", [
343355
operator.eq, operator.ne, operator.gt, operator.lt,

pandas/tests/arithmetic/test_period.py

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222

2323
class TestPeriodIndexComparisons:
2424

25+
# TODO: parameterize over boxes
26+
def test_compare_zerodim(self):
27+
# GH#26689 make sure we unbox zero-dimensional arrays
28+
pi = pd.period_range('2000', periods=4)
29+
other = np.array(pi.to_numpy()[0])
30+
31+
result = pi <= other
32+
expected = np.array([True, False, False, False])
33+
tm.assert_numpy_array_equal(result, expected)
34+
2535
@pytest.mark.parametrize("other", ["2017", 2017])
2636
def test_eq(self, other):
2737
idx = PeriodIndex(['2017', '2017', '2018'], freq="D")

pandas/tests/arithmetic/test_timedelta64.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ def get_upcast_box(box, vector):
3333
class TestTimedelta64ArrayComparisons:
3434
# TODO: All of these need to be parametrized over box
3535

36+
def test_compare_timedelta64_zerodim(self):
37+
# GH#26689 should unbox when comparing with zerodim array
38+
tdi = pd.timedelta_range('2H', periods=4)
39+
other = np.array(tdi.to_numpy()[0])
40+
41+
res = tdi <= other
42+
expected = np.array([True, False, False, False])
43+
tm.assert_numpy_array_equal(res, expected)
44+
45+
with pytest.raises(TypeError):
46+
# zero-dim of wrong dtype should still raise
47+
tdi >= np.array(4)
48+
3649
def test_compare_timedelta_series(self):
3750
# regresssion test for GH#5963
3851
s = pd.Series([timedelta(days=1), timedelta(days=2)])
@@ -1524,7 +1537,8 @@ def test_td64arr_div_nat_invalid(self, box_with_array):
15241537
rng = timedelta_range('1 days', '10 days', name='foo')
15251538
rng = tm.box_expected(rng, box_with_array)
15261539

1527-
with pytest.raises(TypeError, match='true_divide cannot use operands'):
1540+
with pytest.raises(TypeError,
1541+
match="'?true_divide'? cannot use operands"):
15281542
rng / pd.NaT
15291543
with pytest.raises(TypeError, match='Cannot divide NaTType by'):
15301544
pd.NaT / rng

pandas/tests/indexes/timedeltas/test_arithmetic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def test_ops_ndarray(self):
218218
expected = pd.to_timedelta(['2 days']).values
219219
tm.assert_numpy_array_equal(td * np.array([2]), expected)
220220
tm.assert_numpy_array_equal(np.array([2]) * td, expected)
221-
msg = ("ufunc multiply cannot use operands with types"
221+
msg = ("ufunc '?multiply'? cannot use operands with types"
222222
r" dtype\('<m8\[ns\]'\) and dtype\('<m8\[ns\]'\)")
223223
with pytest.raises(TypeError, match=msg):
224224
td * other

pandas/tests/plotting/common.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def setup_method(self, method):
3636

3737
self.mpl_ge_2_2_3 = plotting._compat._mpl_ge_2_2_3()
3838
self.mpl_ge_3_0_0 = plotting._compat._mpl_ge_3_0_0()
39+
self.mpl_ge_3_1_0 = plotting._compat._mpl_ge_3_1_0()
3940

4041
self.bp_n_objects = 7
4142
self.polycollection_factor = 2
@@ -440,10 +441,18 @@ def _check_grid_settings(self, obj, kinds, kws={}):
440441
import matplotlib as mpl
441442

442443
def is_grid_on():
443-
xoff = all(not g.gridOn
444-
for g in self.plt.gca().xaxis.get_major_ticks())
445-
yoff = all(not g.gridOn
446-
for g in self.plt.gca().yaxis.get_major_ticks())
444+
xticks = self.plt.gca().xaxis.get_major_ticks()
445+
yticks = self.plt.gca().yaxis.get_major_ticks()
446+
# for mpl 2.2.2, gridOn and gridline.get_visible disagree.
447+
# for new MPL, they are the same.
448+
449+
if self.mpl_ge_3_0_0:
450+
xoff = all(not g.gridline.get_visible() for g in xticks)
451+
yoff = all(not g.gridline.get_visible() for g in yticks)
452+
else:
453+
xoff = all(not g.gridOn for g in xticks)
454+
yoff = all(not g.gridOn for g in yticks)
455+
447456
return not (xoff and yoff)
448457

449458
spndx = 1

pandas/tests/plotting/test_frame.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,10 @@ def test_subplots(self):
383383
for ax in axes[:-2]:
384384
self._check_visible(ax.xaxis) # xaxis must be visible for grid
385385
self._check_visible(ax.get_xticklabels(), visible=False)
386-
self._check_visible(
387-
ax.get_xticklabels(minor=True), visible=False)
386+
if not (kind == 'bar' and self.mpl_ge_3_1_0):
387+
# change https://github.com/pandas-dev/pandas/issues/26714
388+
self._check_visible(
389+
ax.get_xticklabels(minor=True), visible=False)
388390
self._check_visible(ax.xaxis.get_label(), visible=False)
389391
self._check_visible(ax.get_yticklabels())
390392

@@ -800,7 +802,10 @@ def test_line_area_stacked(self):
800802
with pytest.raises(ValueError):
801803
mixed_df.plot(stacked=True)
802804

803-
_check_plot_works(df.plot, kind=kind, logx=True, stacked=True)
805+
# Use an index with strictly positive values, preventing
806+
# matplotlib from warning about ignoring xlim
807+
df2 = df.set_index(df.index + 1)
808+
_check_plot_works(df2.plot, kind=kind, logx=True, stacked=True)
804809

805810
def test_line_area_nan_df(self):
806811
values1 = [1, 2, np.nan, 3]

requirements-dev.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ python-dateutil>=2.5.0
33
pytz
44
asv
55
cython>=0.28.2
6+
cpplint
67
flake8
78
flake8-comprehensions
89
flake8-rst>=0.6.0,<=0.7.0
910
isort
1011
mypy
1112
pycodestyle
12-
cpplint
1313
gitpython
1414
sphinx
1515
numpydoc>=0.9.0

0 commit comments

Comments
 (0)