Skip to content

Commit f204080

Browse files
authored
Merge pull request #165 from pandas-dev/master
Sync Fork from Upstream Repo
2 parents c56c9d2 + 77ea98e commit f204080

File tree

2 files changed

+49
-56
lines changed

2 files changed

+49
-56
lines changed

.pre-commit-config.yaml

+31-44
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,6 @@ repos:
9090
entry: python scripts/check_for_inconsistent_pandas_namespace.py
9191
language: python
9292
types: [python]
93-
- id: incorrect-code-directives
94-
name: Check for incorrect code block or IPython directives
95-
language: pygrep
96-
entry: (\.\. code-block ::|\.\. ipython ::)
97-
types_or: [python, cython, rst]
9893
- id: no-os-remove
9994
name: Check code for instances of os.remove
10095
entry: os\.remove
@@ -106,49 +101,60 @@ repos:
106101
pandas/tests/io/excel/test_writers\.py
107102
|pandas/tests/io/pytables/common\.py
108103
|pandas/tests/io/pytables/test_store\.py$
109-
- id: non-standard-imports
110-
name: Check for non-standard imports
104+
- id: unwanted-patterns
105+
name: Unwanted patterns
111106
language: pygrep
112107
entry: |
113108
(?x)
114-
# Check for imports from pandas.core.common instead of `import pandas.core.common as com`
115-
from\ pandas\.core\.common\ import
109+
# outdated annotation syntax, missing error codes
110+
\#\ type:\ (?!ignore)
111+
|\#\ type:\s?ignore(?!\[)
112+
113+
# foo._class__ instead of type(foo)
114+
|\.__class__
115+
116+
# np.bool/np.object instead of np.bool_/np.object_
117+
|np\.bool[^_8]
118+
|np\.object[^_8]
119+
120+
# imports from pandas.core.common instead of `import pandas.core.common as com`
121+
|from\ pandas\.core\.common\ import
116122
|from\ pandas\.core\ import\ common
117123
118-
# Check for imports from collections.abc instead of `from collections import abc`
124+
# imports from collections.abc instead of `from collections import abc`
119125
|from\ collections\.abc\ import
120126
121127
# Numpy
122128
|from\ numpy\ import\ random
123129
|from\ numpy\.random\ import
124-
types: [python]
125-
- id: non-standard-imports-in-tests
126-
name: Check for non-standard imports in test suite
130+
131+
# Incorrect code-block / IPython directives
132+
|\.\.\ code-block\ ::
133+
|\.\.\ ipython\ ::
134+
types_or: [python, cython, rst]
135+
exclude: ^doc/source/development/code_style\.rst # contains examples of patterns to avoid
136+
- id: unwanted-patterns-in-tests
137+
name: Unwanted patterns in tests
127138
language: pygrep
128139
entry: |
129140
(?x)
130-
# Check for imports from pandas._testing instead of `import pandas._testing as tm`
131-
from\ pandas\._testing\ import
141+
# pytest.xfail instead of pytest.mark.xfail
142+
pytest\.xfail
143+
144+
# imports from pandas._testing instead of `import pandas._testing as tm`
145+
|from\ pandas\._testing\ import
132146
|from\ pandas\ import\ _testing\ as\ tm
133147
134148
# No direct imports from conftest
135149
|conftest\ import
136150
|import\ conftest
137151
138-
# Check for use of pandas.testing instead of tm
152+
# pandas.testing instead of tm
139153
|pd\.testing\.
140154
141-
# Check for pd.api.types instead of from pandas.api.types import ...
155+
# pd.api.types instead of from pandas.api.types import ...
142156
|(pd|pandas)\.api\.types\.
143-
types: [python]
144157
files: ^pandas/tests/
145-
- id: np-bool-and-np-object
146-
name: Check for use of np.bool/np.object instead of np.bool_/np.object_
147-
entry: |
148-
(?x)
149-
np\.bool[^_8]
150-
|np\.object[^_8]
151-
language: pygrep
152158
types_or: [python, cython, rst]
153159
- id: pip-to-conda
154160
name: Generate pip dependency from conda
@@ -164,11 +170,6 @@ repos:
164170
language: python
165171
types: [rst]
166172
files: ^doc/source/(development|reference)/
167-
- id: type-not-class
168-
name: Check for use of foo.__class__ instead of type(foo)
169-
entry: \.__class__
170-
language: pygrep
171-
types_or: [python, cython]
172173
- id: unwanted-patterns-bare-pytest-raises
173174
name: Check for use of bare pytest raises
174175
language: python
@@ -188,12 +189,6 @@ repos:
188189
entry: python scripts/validate_unwanted_patterns.py --validation-type="private_import_across_module"
189190
types: [python]
190191
exclude: ^(asv_bench|pandas/tests|doc)/
191-
- id: unwanted-patterns-pytest-xfail
192-
name: Check for use of pytest.xfail
193-
entry: pytest\.xfail
194-
language: pygrep
195-
types: [python]
196-
files: ^pandas/tests/
197192
- id: unwanted-patterns-strings-to-concatenate
198193
name: Check for use of not concatenated strings
199194
language: python
@@ -204,14 +199,6 @@ repos:
204199
language: python
205200
entry: python scripts/validate_unwanted_patterns.py --validation-type="strings_with_wrong_placed_whitespace"
206201
types_or: [python, cython]
207-
- id: unwanted-typing
208-
name: Check for outdated annotation syntax and missing error codes
209-
entry: |
210-
(?x)
211-
\#\ type:\ (?!ignore)
212-
|\#\ type:\s?ignore(?!\[)
213-
language: pygrep
214-
types: [python]
215202
- id: use-pd_array-in-core
216203
name: Import pandas.array as pd_array in core
217204
language: python

pandas/core/groupby/ops.py

+18-12
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ def get_iterator(
336336
"""
337337
splitter = self._get_splitter(data, axis=axis)
338338
keys = self._get_group_keys()
339-
for key, (i, group) in zip(keys, splitter):
339+
for key, group in zip(keys, splitter):
340340
yield key, group.__finalize__(data, method="groupby")
341341

342342
@final
@@ -411,21 +411,27 @@ def apply(self, f: F, data: FrameOrSeries, axis: int = 0):
411411
if len(result_values) == len(group_keys):
412412
return group_keys, result_values, mutated
413413

414-
for key, (i, group) in zip(group_keys, splitter):
415-
object.__setattr__(group, "name", key)
416-
414+
if result_values is None:
417415
# result_values is None if fast apply path wasn't taken
418416
# or fast apply aborted with an unexpected exception.
419417
# In either case, initialize the result list and perform
420418
# the slow iteration.
421-
if result_values is None:
422-
result_values = []
423-
419+
result_values = []
420+
skip_first = False
421+
else:
424422
# If result_values is not None we're in the case that the
425423
# fast apply loop was broken prematurely but we have
426424
# already the result for the first group which we can reuse.
427-
elif i == 0:
428-
continue
425+
skip_first = True
426+
427+
# This calls DataSplitter.__iter__
428+
zipped = zip(group_keys, splitter)
429+
if skip_first:
430+
# pop the first item from the front of the iterator
431+
next(zipped)
432+
433+
for key, group in zipped:
434+
object.__setattr__(group, "name", key)
429435

430436
# group might be modified
431437
group_axes = group.axes
@@ -779,7 +785,7 @@ def _aggregate_series_pure_python(self, obj: Series, func: F):
779785

780786
splitter = get_splitter(obj, group_index, ngroups, axis=0)
781787

782-
for label, group in splitter:
788+
for label, group in enumerate(splitter):
783789

784790
# Each step of this loop corresponds to
785791
# libreduction._BaseGrouper._apply_to_group
@@ -1012,8 +1018,8 @@ def __iter__(self):
10121018

10131019
starts, ends = lib.generate_slices(self.slabels, self.ngroups)
10141020

1015-
for i, (start, end) in enumerate(zip(starts, ends)):
1016-
yield i, self._chop(sdata, slice(start, end))
1021+
for start, end in zip(starts, ends):
1022+
yield self._chop(sdata, slice(start, end))
10171023

10181024
@cache_readonly
10191025
def sorted_data(self) -> FrameOrSeries:

0 commit comments

Comments
 (0)