Skip to content

Commit c4878b0

Browse files
committed
Merge remote-tracking branch 'upstream/master' into series_rolling_count_ignores_min_periods
2 parents 554abfa + a3c7722 commit c4878b0

28 files changed

+205
-198
lines changed

.travis.yml

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ python: 3.7
77
# travis cache --delete inside the project directory from the travis command line client
88
# The cache directories will be deleted if anything in ci/ changes in a commit
99
cache:
10-
ccache: true
11-
directories:
12-
- $HOME/.cache # cython cache
13-
- $HOME/.ccache # compiler cache
10+
ccache: true
11+
directories:
12+
- $HOME/.cache # cython cache
13+
- $HOME/.ccache # compiler cache
1414

1515
env:
1616
global:
@@ -20,13 +20,13 @@ env:
2020
- secure: "EkWLZhbrp/mXJOx38CHjs7BnjXafsqHtwxPQrqWy457VDFWhIY1DMnIR/lOWG+a20Qv52sCsFtiZEmMfUjf0pLGXOqurdxbYBGJ7/ikFLk9yV2rDwiArUlVM9bWFnFxHvdz9zewBH55WurrY4ShZWyV+x2dWjjceWG5VpWeI6sA="
2121

2222
git:
23-
# for cloning
24-
depth: false
23+
# for cloning
24+
depth: false
2525

2626
matrix:
27-
fast_finish: true
27+
fast_finish: true
2828

29-
include:
29+
include:
3030
- env:
3131
- JOB="3.8" ENV_FILE="ci/deps/travis-38.yaml" PATTERN="(not slow and not network and not clipboard)"
3232

@@ -40,6 +40,9 @@ matrix:
4040
- postgresql
4141

4242
- env:
43+
# Enabling Deprecations when running tests
44+
# PANDAS_TESTING_MODE="deprecate" causes DeprecationWarning messages to be displayed in the logs
45+
# See pandas/_testing.py for more details.
4346
- JOB="3.6, coverage" ENV_FILE="ci/deps/travis-36-cov.yaml" PATTERN="((not slow and not network and not clipboard) or (single and db))" PANDAS_TESTING_MODE="deprecate" COVERAGE=true SQL="1"
4447
services:
4548
- mysql
@@ -70,7 +73,6 @@ before_install:
7073
# This overrides travis and tells it to look nowhere.
7174
- export BOTO_CONFIG=/dev/null
7275

73-
7476
install:
7577
- echo "install start"
7678
- ci/prep_cython_cache.sh
@@ -87,5 +89,5 @@ script:
8789
after_script:
8890
- echo "after_script start"
8991
- source activate pandas-dev && pushd /tmp && python -c "import pandas; pandas.show_versions();" && popd
90-
- ci/print_skipped.py
92+
- ci/print_skipped.py
9193
- echo "after_script done"

LICENSE

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
BSD 3-Clause License
22

3-
Copyright (c) 2008-2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
3+
Copyright (c) 2008-2011, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
44
All rights reserved.
55

6+
Copyright (c) 2011-2020, Open source contributors.
7+
68
Redistribution and use in source and binary forms, with or without
79
modification, are permitted provided that the following conditions are met:
810

doc/source/development/contributing.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,3 +1525,19 @@ The branch will still exist on GitHub, so to delete it there do::
15251525
git push origin --delete shiny-new-feature
15261526

15271527
.. _Gitter: https://gitter.im/pydata/pandas
1528+
1529+
1530+
Tips for a successful Pull Request
1531+
==================================
1532+
1533+
If you have made it to the `Review your code`_ phase, one of the core contributors may
1534+
take a look. Please note however that a handful of people are responsible for reviewing
1535+
all of the contributions, which can often lead to bottlenecks.
1536+
1537+
To improve the chances of your pull request being reviewed, you should:
1538+
1539+
- **Reference an open issue** for non-trivial changes to clarify the PR's purpose
1540+
- **Ensure you have appropriate tests**. These should be the first part of any PR
1541+
- **Keep your pull requests as simple as possible**. Larger PRs take longer to review
1542+
- **Ensure that CI is in a green state**. Reviewers may not even look otherwise
1543+
- **Keep** `Updating your pull request`_, either by request or every few days

doc/source/whatsnew/v1.1.0.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Categorical
6060
Datetimelike
6161
^^^^^^^^^^^^
6262
- Bug in :class:`Timestamp` where constructing :class:`Timestamp` from ambiguous epoch time and calling constructor again changed :meth:`Timestamp.value` property (:issue:`24329`)
63-
-
63+
- :meth:`DatetimeArray.searchsorted`, :meth:`TimedeltaArray.searchsorted`, :meth:`PeriodArray.searchsorted` not recognizing non-pandas scalars and incorrectly raising ``ValueError`` instead of ``TypeError`` (:issue:`30950`)
6464
-
6565

6666
Timedelta
@@ -102,7 +102,7 @@ Interval
102102

103103
Indexing
104104
^^^^^^^^
105-
105+
- Bug in slicing on a :class:`DatetimeIndex` with a partial-timestamp dropping high-resolution indices near the end of a year, quarter, or month (:issue:`31064`)
106106
-
107107
-
108108

@@ -140,6 +140,7 @@ Reshaping
140140

141141
-
142142
- Bug in :meth:`DataFrame.pivot_table` when only MultiIndexed columns is set (:issue:`17038`)
143+
- Fix incorrect error message in :meth:`DataFrame.pivot` when ``columns`` is set to ``None``. (:issue:`30924`)
143144
- Bug in :func:`crosstab` when inputs are two Series and have tuple names, the output will keep dummy MultiIndex as columns. (:issue:`18321`)
144145

145146

pandas/core/arrays/datetimelike.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,17 +743,36 @@ def searchsorted(self, value, side="left", sorter=None):
743743
Array of insertion points with the same shape as `value`.
744744
"""
745745
if isinstance(value, str):
746-
value = self._scalar_from_string(value)
746+
try:
747+
value = self._scalar_from_string(value)
748+
except ValueError:
749+
raise TypeError("searchsorted requires compatible dtype or scalar")
750+
751+
elif is_valid_nat_for_dtype(value, self.dtype):
752+
value = NaT
753+
754+
elif isinstance(value, self._recognized_scalars):
755+
value = self._scalar_type(value)
756+
757+
elif isinstance(value, np.ndarray):
758+
if not type(self)._is_recognized_dtype(value):
759+
raise TypeError(
760+
"searchsorted requires compatible dtype or scalar, "
761+
f"not {type(value).__name__}"
762+
)
763+
value = type(self)(value)
764+
self._check_compatible_with(value)
747765

748-
if not (isinstance(value, (self._scalar_type, type(self))) or isna(value)):
749-
raise ValueError(f"Unexpected type for 'value': {type(value)}")
766+
if not (isinstance(value, (self._scalar_type, type(self))) or (value is NaT)):
767+
raise TypeError(f"Unexpected type for 'value': {type(value)}")
750768

751-
self._check_compatible_with(value)
752769
if isinstance(value, type(self)):
770+
self._check_compatible_with(value)
753771
value = value.asi8
754772
else:
755773
value = self._unbox_scalar(value)
756774

775+
# TODO: Use datetime64 semantics for sorting, xref GH#29844
757776
return self.asi8.searchsorted(value, side=side, sorter=sorter)
758777

759778
def repeat(self, repeats, *args, **kwargs):

pandas/core/arrays/period.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,9 @@ def __init__(self, values, freq=None, dtype=None, copy=False):
169169
self._dtype = PeriodDtype(freq)
170170

171171
@classmethod
172-
def _simple_new(cls, values, freq=None, **kwargs):
172+
def _simple_new(cls, values: np.ndarray, freq=None, **kwargs):
173173
# alias for PeriodArray.__init__
174+
assert isinstance(values, np.ndarray) and values.dtype == "i8"
174175
return cls(values, freq=freq, **kwargs)
175176

176177
@classmethod

pandas/core/base.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,12 +583,10 @@ def _is_builtin_func(self, arg):
583583
class ShallowMixin:
584584
_attributes: List[str] = []
585585

586-
def _shallow_copy(self, obj=None, **kwargs):
586+
def _shallow_copy(self, obj, **kwargs):
587587
"""
588588
return a new object with the replacement attributes
589589
"""
590-
if obj is None:
591-
obj = self._selected_obj.copy()
592590

593591
if isinstance(obj, self._constructor):
594592
obj = obj.obj

pandas/core/frame.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2749,14 +2749,7 @@ def _ixs(self, i: int, axis: int = 0):
27492749
else:
27502750
label = self.columns[i]
27512751

2752-
# if the values returned are not the same length
2753-
# as the index (iow a not found value), iget returns
2754-
# a 0-len ndarray. This is effectively catching
2755-
# a numpy error (as numpy should really raise)
27562752
values = self._data.iget(i)
2757-
2758-
if len(self.index) and not len(values):
2759-
values = np.array([np.nan] * len(self.index), dtype=object)
27602753
result = self._box_col_values(values, label)
27612754

27622755
# this is a cached value, mark it so

pandas/core/generic.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3173,19 +3173,6 @@ def to_csv(
31733173

31743174
return None
31753175

3176-
# ----------------------------------------------------------------------
3177-
# Fancy Indexing
3178-
3179-
@classmethod
3180-
def _create_indexer(cls, name: str, indexer) -> None:
3181-
"""Create an indexer like _name in the class.
3182-
3183-
Kept for compatibility with geopandas. To be removed in the future. See GH27258
3184-
"""
3185-
if getattr(cls, name, None) is None:
3186-
_indexer = functools.partial(indexer, name)
3187-
setattr(cls, name, property(_indexer, doc=indexer.__doc__))
3188-
31893176
# ----------------------------------------------------------------------
31903177
# Lookup Caching
31913178

@@ -3579,14 +3566,12 @@ def _set_item(self, key, value) -> None:
35793566
self._data.set(key, value)
35803567
self._clear_item_cache()
35813568

3582-
def _set_is_copy(self, ref=None, copy: bool_t = True) -> None:
3569+
def _set_is_copy(self, ref, copy: bool_t = True) -> None:
35833570
if not copy:
35843571
self._is_copy = None
35853572
else:
3586-
if ref is not None:
3587-
self._is_copy = weakref.ref(ref)
3588-
else:
3589-
self._is_copy = None
3573+
assert ref is not None
3574+
self._is_copy = weakref.ref(ref)
35903575

35913576
def _check_is_chained_assignment_possible(self) -> bool_t:
35923577
"""

pandas/core/indexes/base.py

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
from pandas.core.dtypes.generic import (
5151
ABCCategorical,
5252
ABCDataFrame,
53-
ABCDatetimeArray,
5453
ABCDatetimeIndex,
5554
ABCIndexClass,
5655
ABCIntervalIndex,
@@ -460,11 +459,7 @@ def _simple_new(cls, values, name=None, dtype=None):
460459
461460
Must be careful not to recurse.
462461
"""
463-
if isinstance(values, (ABCSeries, ABCIndexClass)):
464-
# Index._data must always be an ndarray.
465-
# This is no-copy for when _values is an ndarray,
466-
# which should be always at this point.
467-
values = np.asarray(values._values)
462+
assert isinstance(values, np.ndarray), type(values)
468463

469464
result = object.__new__(cls)
470465
result._data = values
@@ -510,17 +505,14 @@ def _get_attributes_dict(self):
510505
def _shallow_copy(self, values=None, **kwargs):
511506
if values is None:
512507
values = self.values
508+
513509
attributes = self._get_attributes_dict()
514510
attributes.update(kwargs)
515511
if not len(values) and "dtype" not in kwargs:
516512
attributes["dtype"] = self.dtype
517513

518514
# _simple_new expects an the type of self._data
519515
values = getattr(values, "_values", values)
520-
if isinstance(values, ABCDatetimeArray):
521-
# `self.values` returns `self` for tz-aware, so we need to unwrap
522-
# more specifically
523-
values = values.asi8
524516

525517
return self._simple_new(values, **attributes)
526518

@@ -3129,7 +3121,7 @@ def _convert_scalar_indexer(self, key, kind=None):
31293121

31303122
if kind in ["getitem"] and is_float(key):
31313123
if not self.is_floating():
3132-
return self._invalid_indexer("label", key)
3124+
self._invalid_indexer("label", key)
31333125

31343126
elif kind in ["loc"] and is_float(key):
31353127

@@ -4621,34 +4613,31 @@ def argsort(self, *args, **kwargs) -> np.ndarray:
46214613
@Appender(_index_shared_docs["get_value"] % _index_doc_kwargs)
46224614
def get_value(self, series, key):
46234615

4616+
if not is_scalar(key):
4617+
# if key is not a scalar, directly raise an error (the code below
4618+
# would convert to numpy arrays and raise later any way) - GH29926
4619+
raise InvalidIndexError(key)
4620+
46244621
# if we have something that is Index-like, then
46254622
# use this, e.g. DatetimeIndex
46264623
# Things like `Series._get_value` (via .at) pass the EA directly here.
46274624
s = extract_array(series, extract_numpy=True)
46284625
if isinstance(s, ExtensionArray):
4629-
if is_scalar(key):
4630-
# GH 20882, 21257
4631-
# First try to convert the key to a location
4632-
# If that fails, raise a KeyError if an integer
4633-
# index, otherwise, see if key is an integer, and
4634-
# try that
4635-
try:
4636-
iloc = self.get_loc(key)
4637-
return s[iloc]
4638-
except KeyError:
4639-
if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
4640-
raise
4641-
elif is_integer(key):
4642-
return s[key]
4643-
else:
4644-
# if key is not a scalar, directly raise an error (the code below
4645-
# would convert to numpy arrays and raise later any way) - GH29926
4646-
raise InvalidIndexError(key)
4647-
4648-
s = com.values_from_object(series)
4649-
k = com.values_from_object(key)
4626+
# GH 20882, 21257
4627+
# First try to convert the key to a location
4628+
# If that fails, raise a KeyError if an integer
4629+
# index, otherwise, see if key is an integer, and
4630+
# try that
4631+
try:
4632+
iloc = self.get_loc(key)
4633+
return s[iloc]
4634+
except KeyError:
4635+
if len(self) > 0 and (self.holds_integer() or self.is_boolean()):
4636+
raise
4637+
elif is_integer(key):
4638+
return s[key]
46504639

4651-
k = self._convert_scalar_indexer(k, kind="getitem")
4640+
k = self._convert_scalar_indexer(key, kind="getitem")
46524641
try:
46534642
return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
46544643
except KeyError as e1:

pandas/core/indexes/category.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,8 @@ def get_value(self, series: AnyArrayLike, key: Any):
503503
Any
504504
The element of the series at the position indicated by the key
505505
"""
506+
k = key
506507
try:
507-
k = com.values_from_object(key)
508508
k = self._convert_scalar_indexer(k, kind="getitem")
509509
indexer = self.get_loc(k)
510510
return series.take([indexer])[0]

0 commit comments

Comments
 (0)