Skip to content

Commit ebad8a4

Browse files
Merge remote-tracking branch 'upstream/master' into am-concat
2 parents 555d7ac + 3f944b9 commit ebad8a4

Some content is hidden

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

41 files changed

+887
-403
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ repos:
2424
hooks:
2525
- id: isort
2626
- repo: https://github.com/asottile/pyupgrade
27-
rev: v2.9.0
27+
rev: v2.10.0
2828
hooks:
2929
- id: pyupgrade
3030
args: [--py37-plus, --keep-runtime-typing]
3131
- repo: https://github.com/pre-commit/pygrep-hooks
32-
rev: v1.7.0
32+
rev: v1.7.1
3333
hooks:
3434
- id: rst-backticks
3535
- id: rst-directive-colons

asv_bench/benchmarks/categoricals.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,29 @@ def setup(self):
118118
self.a = pd.Categorical(list("aabbcd") * N)
119119
self.b = pd.Categorical(list("bbcdjk") * N)
120120

121+
self.idx_a = pd.CategoricalIndex(range(N), range(N))
122+
self.idx_b = pd.CategoricalIndex(range(N + 1), range(N + 1))
123+
self.df_a = pd.DataFrame(range(N), columns=["a"], index=self.idx_a)
124+
self.df_b = pd.DataFrame(range(N + 1), columns=["a"], index=self.idx_b)
125+
121126
def time_concat(self):
122127
pd.concat([self.s, self.s])
123128

124129
def time_union(self):
125130
union_categoricals([self.a, self.b])
126131

132+
def time_append_overlapping_index(self):
133+
self.idx_a.append(self.idx_a)
134+
135+
def time_append_non_overlapping_index(self):
136+
self.idx_a.append(self.idx_b)
137+
138+
def time_concat_overlapping_index(self):
139+
pd.concat([self.df_a, self.df_a])
140+
141+
def time_concat_non_overlapping_index(self):
142+
pd.concat([self.df_a, self.df_b])
143+
127144

128145
class ValueCounts:
129146

asv_bench/benchmarks/hash_functions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ def time_isin_outside(self, dtype, exponent):
2525
self.s.isin(self.values_outside)
2626

2727

28+
class UniqueForLargePyObjectInts:
29+
def setup(self):
30+
lst = [x << 32 for x in range(5000)]
31+
self.arr = np.array(lst, dtype=np.object_)
32+
33+
def time_unique(self):
34+
pd.unique(self.arr)
35+
36+
2837
class IsinWithRandomFloat:
2938
params = [
3039
[np.float64, np.object],

asv_bench/benchmarks/rolling.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,11 @@ class Pairwise:
140140

141141
def setup(self, window, method, pairwise):
142142
N = 10 ** 4
143+
n_groups = 20
144+
groups = [i for _ in range(N // n_groups) for i in range(n_groups)]
143145
arr = np.random.random(N)
144146
self.df = pd.DataFrame(arr)
147+
self.df_group = pd.DataFrame({"A": groups, "B": arr}).groupby("A")
145148

146149
def time_pairwise(self, window, method, pairwise):
147150
if window is None:
@@ -150,6 +153,13 @@ def time_pairwise(self, window, method, pairwise):
150153
r = self.df.rolling(window=window)
151154
getattr(r, method)(self.df, pairwise=pairwise)
152155

156+
def time_groupby(self, window, method, pairwise):
157+
if window is None:
158+
r = self.df_group.expanding()
159+
else:
160+
r = self.df_group.rolling(window=window)
161+
getattr(r, method)(self.df, pairwise=pairwise)
162+
153163

154164
class Quantile:
155165
params = (

doc/source/development/extending.rst

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,11 @@ Each data structure has several *constructor properties* for returning a new
329329
data structure as the result of an operation. By overriding these properties,
330330
you can retain subclasses through ``pandas`` data manipulations.
331331

332-
There are 3 constructor properties to be defined:
332+
There are 3 possible constructor properties to be defined on a subclass:
333333

334-
* ``_constructor``: Used when a manipulation result has the same dimensions as the original.
335-
* ``_constructor_sliced``: Used when a manipulation result has one lower dimension(s) as the original, such as ``DataFrame`` single columns slicing.
336-
* ``_constructor_expanddim``: Used when a manipulation result has one higher dimension as the original, such as ``Series.to_frame()``.
337-
338-
Following table shows how ``pandas`` data structures define constructor properties by default.
339-
340-
=========================== ======================= =============
341-
Property Attributes ``Series`` ``DataFrame``
342-
=========================== ======================= =============
343-
``_constructor`` ``Series`` ``DataFrame``
344-
``_constructor_sliced`` ``NotImplementedError`` ``Series``
345-
``_constructor_expanddim`` ``DataFrame`` ``NotImplementedError``
346-
=========================== ======================= =============
334+
* ``DataFrame/Series._constructor``: Used when a manipulation result has the same dimension as the original.
335+
* ``DataFrame._constructor_sliced``: Used when a ``DataFrame`` (sub-)class manipulation result should be a ``Series`` (sub-)class.
336+
* ``Series._constructor_expanddim``: Used when a ``Series`` (sub-)class manipulation result should be a ``DataFrame`` (sub-)class, e.g. ``Series.to_frame()``.
347337

348338
Below example shows how to define ``SubclassedSeries`` and ``SubclassedDataFrame`` overriding constructor properties.
349339

doc/source/user_guide/style.ipynb

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@
180180
"\n",
181181
"styles = [\n",
182182
" hover(),\n",
183-
" {'selector': \"th\", 'props': [(\"font-size\", \"150%\"),\n",
184-
" (\"text-align\", \"center\")]}\n",
183+
" {'selector': \"th\", 'props': [(\"font-size\", \"150%\"), (\"text-align\", \"center\")]}\n",
185184
"]\n",
186185
"\n",
187186
"df.style.set_table_styles(styles)"
@@ -224,7 +223,7 @@
224223
"cell_type": "markdown",
225224
"metadata": {},
226225
"source": [
227-
"We can also chain all of the above by setting the `overwrite` argument to `False` so that it preserves previous settings."
226+
"We can also chain all of the above by setting the `overwrite` argument to `False` so that it preserves previous settings. We also show the CSS string input rather than the list of tuples."
228227
]
229228
},
230229
{
@@ -238,13 +237,13 @@
238237
" set_table_styles(styles).\\\n",
239238
" set_table_styles({\n",
240239
" 'A': [{'selector': '',\n",
241-
" 'props': [('color', 'red')]}],\n",
240+
" 'props': 'color:red;'}],\n",
242241
" 'B': [{'selector': 'td',\n",
243-
" 'props': [('color', 'blue')]}]\n",
242+
" 'props': 'color:blue;'}]\n",
244243
" }, axis=0, overwrite=False).\\\n",
245244
" set_table_styles({\n",
246245
" 3: [{'selector': 'td',\n",
247-
" 'props': [('color', 'green')]}]\n",
246+
" 'props': 'color:green;font-weight:bold;'}]\n",
248247
" }, axis=1, overwrite=False)\n",
249248
"s"
250249
]

doc/source/whatsnew/v1.2.2.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ Fixed regressions
1717

1818
- Fixed regression in :func:`read_excel` that caused it to raise ``AttributeError`` when checking version of older xlrd versions (:issue:`38955`)
1919
- Fixed regression in :class:`DataFrame` constructor reordering element when construction from datetime ndarray with dtype not ``"datetime64[ns]"`` (:issue:`39422`)
20-
- Fixed regression in :class:`DataFrame.astype` and :class:`Series.astype` not casting to bytes dtype (:issue:`39474`)
20+
- Fixed regression in :meth:`DataFrame.astype` and :meth:`Series.astype` not casting to bytes dtype (:issue:`39474`)
2121
- Fixed regression in :meth:`~DataFrame.to_pickle` failing to create bz2/xz compressed pickle files with ``protocol=5`` (:issue:`39002`)
2222
- Fixed regression in :func:`pandas.testing.assert_series_equal` and :func:`pandas.testing.assert_frame_equal` always raising ``AssertionError`` when comparing extension dtypes (:issue:`39410`)
2323
- Fixed regression in :meth:`~DataFrame.to_csv` opening ``codecs.StreamWriter`` in binary mode instead of in text mode and ignoring user-provided ``mode`` (:issue:`39247`)
24+
- Fixed regression in :meth:`~DataFrame.to_excel` creating corrupt files when appending (``mode="a"``) to an existing file (:issue:`39576`)
25+
- Fixed regression in :meth:`DataFrame.transform` failing in case of an empty DataFrame or Series (:issue:`39636`)
26+
- Fixed regression in :meth:`core.window.rolling.Rolling.count` where the ``min_periods`` argument would be set to ``0`` after the operation (:issue:`39554`)
27+
- Fixed regression in :func:`read_excel` that incorrectly raised when the argument ``io`` was a non-path and non-buffer and the ``engine`` argument was specified (:issue:`39528`)
2428
-
2529

2630
.. ---------------------------------------------------------------------------

doc/source/whatsnew/v1.3.0.rst

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ Other enhancements
5353
- :meth:`DataFrame.apply` can now accept non-callable DataFrame properties as strings, e.g. ``df.apply("size")``, which was already the case for :meth:`Series.apply` (:issue:`39116`)
5454
- :meth:`Series.apply` can now accept list-like or dictionary-like arguments that aren't lists or dictionaries, e.g. ``ser.apply(np.array(["sum", "mean"]))``, which was already the case for :meth:`DataFrame.apply` (:issue:`39140`)
5555
- :meth:`DataFrame.plot.scatter` can now accept a categorical column as the argument to ``c`` (:issue:`12380`, :issue:`31357`)
56-
- :meth:`.Styler.set_tooltips` allows on hover tooltips to be added to styled HTML dataframes.
56+
- :meth:`.Styler.set_tooltips` allows on hover tooltips to be added to styled HTML dataframes (:issue:`35643`)
57+
- :meth:`.Styler.set_tooltips_class` and :meth:`.Styler.set_table_styles` amended to optionally allow certain css-string input arguments (:issue:`39564`)
5758
- :meth:`Series.loc.__getitem__` and :meth:`Series.loc.__setitem__` with :class:`MultiIndex` now raising helpful error message when indexer has too many dimensions (:issue:`35349`)
5859
- :meth:`pandas.read_stata` and :class:`StataReader` support reading data from compressed files.
5960

61+
6062
.. ---------------------------------------------------------------------------
6163
6264
.. _whatsnew_130.notable_bug_fixes:
@@ -217,7 +219,7 @@ See :ref:`install.dependencies` and :ref:`install.optional_dependencies` for mor
217219
Other API changes
218220
^^^^^^^^^^^^^^^^^
219221
- Partially initialized :class:`CategoricalDtype` (i.e. those with ``categories=None`` objects will no longer compare as equal to fully initialized dtype objects.
220-
-
222+
- Accessing ``_constructor_expanddim`` on a :class:`DataFrame` and ``_constructor_sliced`` on a :class:`Series` now raise an ``AttributeError``. Previously a ``NotImplementedError`` was raised (:issue:`38782`)
221223
-
222224

223225
.. ---------------------------------------------------------------------------
@@ -249,7 +251,9 @@ Performance improvements
249251
- Performance improvement in :meth:`Series.mean` for nullable data types (:issue:`34814`)
250252
- Performance improvement in :meth:`Series.isin` for nullable data types (:issue:`38340`)
251253
- Performance improvement in :meth:`DataFrame.corr` for method=kendall (:issue:`28329`)
252-
- Performance improvement in :meth:`core.window.Rolling.corr` and :meth:`core.window.Rolling.cov` (:issue:`39388`)
254+
- Performance improvement in :meth:`core.window.rolling.Rolling.corr` and :meth:`core.window.rolling.Rolling.cov` (:issue:`39388`)
255+
- Performance improvement in :meth:`core.window.rolling.RollingGroupby.corr`, :meth:`core.window.expanding.ExpandingGroupby.corr`, :meth:`core.window.expanding.ExpandingGroupby.corr` and :meth:`core.window.expanding.ExpandingGroupby.cov` (:issue:`39591`)
256+
- Performance improvement in :func:`unique` for object data type (:issue:`37615`)
253257

254258
.. ---------------------------------------------------------------------------
255259
@@ -301,6 +305,7 @@ Numeric
301305
- Bug in :meth:`DataFrame.mode` and :meth:`Series.mode` not keeping consistent integer :class:`Index` for empty input (:issue:`33321`)
302306
- Bug in :meth:`DataFrame.rank` with ``np.inf`` and mixture of ``np.nan`` and ``np.inf`` (:issue:`32593`)
303307
- Bug in :meth:`DataFrame.rank` with ``axis=0`` and columns holding incomparable types raising ``IndexError`` (:issue:`38932`)
308+
- Bug in :func:`select_dtypes` different behavior between Windows and Linux with ``include="int"`` (:issue:`36569`)
304309
-
305310

306311
Conversion
@@ -335,7 +340,7 @@ Indexing
335340
- Bug in :meth:`Series.__setitem__` raising ``ValueError`` when setting a :class:`Series` with a scalar indexer (:issue:`38303`)
336341
- Bug in :meth:`DataFrame.loc` dropping levels of :class:`MultiIndex` when :class:`DataFrame` used as input has only one row (:issue:`10521`)
337342
- Bug in :meth:`DataFrame.__getitem__` and :meth:`Series.__getitem__` always raising ``KeyError`` when slicing with existing strings an :class:`Index` with milliseconds (:issue:`33589`)
338-
- Bug in setting ``timedelta64`` values into numeric :class:`Series` failing to cast to object dtype (:issue:`39086`)
343+
- Bug in setting ``timedelta64`` or ``datetime64`` values into numeric :class:`Series` failing to cast to object dtype (:issue:`39086`, issue:`39619`)
339344
- Bug in setting :class:`Interval` values into a :class:`Series` or :class:`DataFrame` with mismatched :class:`IntervalDtype` incorrectly casting the new values to the existing dtype (:issue:`39120`)
340345
- Bug in setting ``datetime64`` values into a :class:`Series` with integer-dtype incorrect casting the datetime64 values to integers (:issue:`39266`)
341346
- Bug in :meth:`Index.get_loc` not raising ``KeyError`` when method is specified for ``NaN`` value when ``NaN`` is not in :class:`Index` (:issue:`39382`)
@@ -407,6 +412,8 @@ Groupby/resample/rolling
407412
- Bug in :meth:`.Resampler.aggregate` and :meth:`DataFrame.transform` raising ``TypeError`` instead of ``SpecificationError`` when missing keys had mixed dtypes (:issue:`39025`)
408413
- Bug in :meth:`.DataFrameGroupBy.idxmin` and :meth:`.DataFrameGroupBy.idxmax` with ``ExtensionDtype`` columns (:issue:`38733`)
409414
- Bug in :meth:`Series.resample` would raise when the index was a :class:`PeriodIndex` consisting of ``NaT`` (:issue:`39227`)
415+
- Bug in :meth:`core.window.rolling.RollingGroupby.corr` and :meth:`core.window.expanding.ExpandingGroupby.corr` where the groupby column would return 0 instead of ``np.nan`` when providing ``other`` that was longer than each group (:issue:`39591`)
416+
- Bug in :meth:`core.window.expanding.ExpandingGroupby.corr` and :meth:`core.window.expanding.ExpandingGroupby.cov` where 1 would be returned instead of ``np.nan`` when providing ``other`` that was longer than each group (:issue:`39591`)
410417

411418
Reshaping
412419
^^^^^^^^^
@@ -440,10 +447,11 @@ Other
440447
- Bug in :class:`Index` constructor sometimes silently ignorning a specified ``dtype`` (:issue:`38879`)
441448
- Bug in constructing a :class:`Series` from a list and a :class:`PandasDtype` (:issue:`39357`)
442449
- Bug in :class:`Styler` which caused CSS to duplicate on multiple renders. (:issue:`39395`)
450+
- ``inspect.getmembers(Series)`` no longer raises an ``AbstractMethodError`` (:issue:`38782`)
443451
- :meth:`Index.where` behavior now mirrors :meth:`Index.putmask` behavior, i.e. ``index.where(mask, other)`` matches ``index.putmask(~mask, other)`` (:issue:`39412`)
444452
- Bug in :func:`pandas.testing.assert_series_equal`, :func:`pandas.testing.assert_frame_equal`, :func:`pandas.testing.assert_index_equal` and :func:`pandas.testing.assert_extension_array_equal` incorrectly raising when an attribute has an unrecognized NA type (:issue:`39461`)
445453
- Bug in :class:`Styler` where ``subset`` arg in methods raised an error for some valid multiindex slices (:issue:`33562`)
446-
-
454+
- :class:`Styler` rendered HTML output minor alterations to support w3 good code standard (:issue:`39626`)
447455
-
448456

449457
.. ---------------------------------------------------------------------------

pandas/_libs/index_class_helper.pxi.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,14 @@ cdef class {{name}}Engine(IndexEngine):
3434
cdef _make_hash_table(self, Py_ssize_t n):
3535
return _hash.{{name}}HashTable(n)
3636

37-
{{if name not in {'Float64', 'Float32'} }}
3837
cdef _check_type(self, object val):
38+
{{if name not in {'Float64', 'Float32'} }}
3939
if not util.is_integer_object(val):
4040
raise KeyError(val)
41+
{{else}}
42+
if util.is_bool_object(val):
43+
# avoid casting to True -> 1.0
44+
raise KeyError(val)
4145
{{endif}}
4246

4347
cdef void _call_map_locations(self, values):

pandas/_libs/src/klib/khash_python.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,31 @@ int PANDAS_INLINE pyobject_cmp(PyObject* a, PyObject* b) {
178178
return result;
179179
}
180180

181-
// For PyObject_Hash holds:
182-
// hash(0.0) == 0 == hash(-0.0)
183-
// hash(X) == 0 if X is a NaN-value
184-
// so it is OK to use it directly
185-
#define kh_python_hash_func(key) (PyObject_Hash(key))
181+
182+
khint32_t PANDAS_INLINE kh_python_hash_func(PyObject* key){
183+
// For PyObject_Hash holds:
184+
// hash(0.0) == 0 == hash(-0.0)
185+
// hash(X) == 0 if X is a NaN-value
186+
// so it is OK to use it directly for doubles
187+
Py_hash_t hash = PyObject_Hash(key);
188+
if (hash == -1) {
189+
PyErr_Clear();
190+
return 0;
191+
}
192+
#if SIZEOF_PY_HASH_T == 4
193+
// it is already 32bit value
194+
return hash;
195+
#else
196+
// for 64bit builds,
197+
// we need information of the upper 32bits as well
198+
// see GH 37615
199+
khuint64_t as_uint = (khuint64_t) hash;
200+
// uints avoid undefined behavior of signed ints
201+
return (as_uint>>32)^as_uint;
202+
#endif
203+
}
204+
205+
186206
#define kh_python_hash_equal(a, b) (pyobject_cmp(a, b))
187207

188208

pandas/core/aggregation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ def transform(
457457

458458
# Functions that transform may return empty Series/DataFrame
459459
# when the dtype is not appropriate
460-
if isinstance(result, (ABCSeries, ABCDataFrame)) and result.empty:
460+
if isinstance(result, (ABCSeries, ABCDataFrame)) and result.empty and not obj.empty:
461461
raise ValueError("Transform function failed")
462462
if not isinstance(result, (ABCSeries, ABCDataFrame)) or not result.index.equals(
463463
obj.index

pandas/core/algorithms.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@ def unique(values):
324324
Hash table-based unique. Uniques are returned in order
325325
of appearance. This does NOT sort.
326326
327-
Significantly faster than numpy.unique. Includes NA values.
327+
Significantly faster than numpy.unique for long enough sequences.
328+
Includes NA values.
328329
329330
Parameters
330331
----------

0 commit comments

Comments
 (0)