Skip to content

Commit 5d62933

Browse files
committed
Add _typing.FrameOrSeries
1 parent cd0146d commit 5d62933

File tree

11 files changed

+73
-69
lines changed

11 files changed

+73
-69
lines changed

Diff for: pandas/_typing.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
from pandas.core.arrays.base import ExtensionArray # noqa: F401
2222
from pandas.core.dtypes.dtypes import ExtensionDtype # noqa: F401
2323
from pandas.core.indexes.base import Index # noqa: F401
24-
from pandas.core.series import Series # noqa: F401
2524
from pandas.core.generic import NDFrame # noqa: F401
2625
from pandas import Interval # noqa: F401
26+
from pandas.core.series import Series # noqa: F401
27+
from pandas.core.frame import DataFrame # noqa: F401
2728

2829
# array-like
2930

@@ -41,7 +42,8 @@
4142

4243
Dtype = Union[str, np.dtype, "ExtensionDtype"]
4344
FilePathOrBuffer = Union[str, Path, IO[AnyStr]]
44-
FrameOrSeries = TypeVar("FrameOrSeries", bound="NDFrame")
45+
FrameOrSeries = Union["DataFrame", "Series"]
46+
FrameOrSeriesT = TypeVar("FrameOrSeriesT", bound="NDFrame")
4547
Axis = Union[str, int]
4648
Ordered = Optional[bool]
4749
JSONSerializable = Union[PythonScalar, List, Dict]

Diff for: pandas/core/generic.py

+27-27
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from pandas._config import config
3030

3131
from pandas._libs import Timestamp, iNaT, lib, properties
32-
from pandas._typing import Dtype, FilePathOrBuffer, FrameOrSeries, JSONSerializable
32+
from pandas._typing import Dtype, FilePathOrBuffer, FrameOrSeriesT, JSONSerializable
3333
from pandas.compat import set_function_name
3434
from pandas.compat._optional import import_optional_dependency
3535
from pandas.compat.numpy import function as nv
@@ -542,12 +542,12 @@ def size(self):
542542
return np.prod(self.shape)
543543

544544
@property
545-
def _selected_obj(self: FrameOrSeries) -> FrameOrSeries:
545+
def _selected_obj(self: FrameOrSeriesT) -> FrameOrSeriesT:
546546
""" internal compat with SelectionMixin """
547547
return self
548548

549549
@property
550-
def _obj_with_exclusions(self: FrameOrSeries) -> FrameOrSeries:
550+
def _obj_with_exclusions(self: FrameOrSeriesT) -> FrameOrSeriesT:
551551
""" internal compat with SelectionMixin """
552552
return self
553553

@@ -4644,7 +4644,7 @@ def f(x):
46444644
else:
46454645
raise TypeError("Must pass either `items`, `like`, or `regex`")
46464646

4647-
def head(self: FrameOrSeries, n: int = 5) -> FrameOrSeries:
4647+
def head(self: FrameOrSeriesT, n: int = 5) -> FrameOrSeriesT:
46484648
"""
46494649
Return the first `n` rows.
46504650
@@ -4717,7 +4717,7 @@ def head(self: FrameOrSeries, n: int = 5) -> FrameOrSeries:
47174717

47184718
return self.iloc[:n]
47194719

4720-
def tail(self: FrameOrSeries, n: int = 5) -> FrameOrSeries:
4720+
def tail(self: FrameOrSeriesT, n: int = 5) -> FrameOrSeriesT:
47214721
"""
47224722
Return the last `n` rows.
47234723
@@ -5162,8 +5162,8 @@ def pipe(self, func, *args, **kwargs):
51625162
# Attribute access
51635163

51645164
def __finalize__(
5165-
self: FrameOrSeries, other, method=None, **kwargs
5166-
) -> FrameOrSeries:
5165+
self: FrameOrSeriesT, other, method=None, **kwargs
5166+
) -> FrameOrSeriesT:
51675167
"""
51685168
Propagate metadata from other to self.
51695169
@@ -5630,7 +5630,7 @@ def astype(self, dtype, copy: bool_t = True, errors: str = "raise"):
56305630
result.columns = self.columns
56315631
return result
56325632

5633-
def copy(self: FrameOrSeries, deep: bool_t = True) -> FrameOrSeries:
5633+
def copy(self: FrameOrSeriesT, deep: bool_t = True) -> FrameOrSeriesT:
56345634
"""
56355635
Make a copy of this object's indices and data.
56365636
@@ -5738,10 +5738,10 @@ def copy(self: FrameOrSeries, deep: bool_t = True) -> FrameOrSeries:
57385738
data = self._data.copy(deep=deep)
57395739
return self._constructor(data).__finalize__(self)
57405740

5741-
def __copy__(self: FrameOrSeries, deep: bool_t = True) -> FrameOrSeries:
5741+
def __copy__(self: FrameOrSeriesT, deep: bool_t = True) -> FrameOrSeriesT:
57425742
return self.copy(deep=deep)
57435743

5744-
def __deepcopy__(self: FrameOrSeries, memo=None) -> FrameOrSeries:
5744+
def __deepcopy__(self: FrameOrSeriesT, memo=None) -> FrameOrSeriesT:
57455745
"""
57465746
Parameters
57475747
----------
@@ -5751,13 +5751,13 @@ def __deepcopy__(self: FrameOrSeries, memo=None) -> FrameOrSeries:
57515751
return self.copy(deep=True)
57525752

57535753
def _convert(
5754-
self: FrameOrSeries,
5754+
self: FrameOrSeriesT,
57555755
datetime: bool_t = False,
57565756
numeric: bool_t = False,
57575757
timedelta: bool_t = False,
57585758
coerce: bool_t = False,
57595759
copy: bool_t = True,
5760-
) -> FrameOrSeries:
5760+
) -> FrameOrSeriesT:
57615761
"""
57625762
Attempt to infer better dtype for object columns
57635763
@@ -5849,14 +5849,14 @@ def infer_objects(self):
58495849
# Filling NA's
58505850

58515851
def fillna(
5852-
self: FrameOrSeries,
5852+
self: FrameOrSeriesT,
58535853
value=None,
58545854
method=None,
58555855
axis=None,
58565856
inplace: bool_t = False,
58575857
limit=None,
58585858
downcast=None,
5859-
) -> Optional[FrameOrSeries]:
5859+
) -> Optional[FrameOrSeriesT]:
58605860
"""
58615861
Fill NA/NaN values using the specified method.
58625862
@@ -6038,12 +6038,12 @@ def fillna(
60386038
return self._constructor(new_data).__finalize__(self)
60396039

60406040
def ffill(
6041-
self: FrameOrSeries,
6041+
self: FrameOrSeriesT,
60426042
axis=None,
60436043
inplace: bool_t = False,
60446044
limit=None,
60456045
downcast=None,
6046-
) -> Optional[FrameOrSeries]:
6046+
) -> Optional[FrameOrSeriesT]:
60476047
"""
60486048
Synonym for :meth:`DataFrame.fillna` with ``method='ffill'``.
60496049
@@ -6057,12 +6057,12 @@ def ffill(
60576057
)
60586058

60596059
def bfill(
6060-
self: FrameOrSeries,
6060+
self: FrameOrSeriesT,
60616061
axis=None,
60626062
inplace: bool_t = False,
60636063
limit=None,
60646064
downcast=None,
6065-
) -> Optional[FrameOrSeries]:
6065+
) -> Optional[FrameOrSeriesT]:
60666066
"""
60676067
Synonym for :meth:`DataFrame.fillna` with ``method='bfill'``.
60686068
@@ -8025,14 +8025,14 @@ def last(self, offset):
80258025
return self.iloc[start:]
80268026

80278027
def rank(
8028-
self: FrameOrSeries,
8028+
self: FrameOrSeriesT,
80298029
axis=0,
80308030
method: str = "average",
80318031
numeric_only: Optional[bool_t] = None,
80328032
na_option: str = "keep",
80338033
ascending: bool_t = True,
80348034
pct: bool_t = False,
8035-
) -> FrameOrSeries:
8035+
) -> FrameOrSeriesT:
80368036
"""
80378037
Compute numerical data ranks (1 through n) along axis.
80388038
@@ -8834,7 +8834,7 @@ def shift(self, periods=1, freq=None, axis=0, fill_value=None):
88348834

88358835
return self._constructor(new_data).__finalize__(self)
88368836

8837-
def slice_shift(self: FrameOrSeries, periods: int = 1, axis=0) -> FrameOrSeries:
8837+
def slice_shift(self: FrameOrSeriesT, periods: int = 1, axis=0) -> FrameOrSeriesT:
88388838
"""
88398839
Equivalent to `shift` without copying data.
88408840
@@ -8932,8 +8932,8 @@ def tshift(self, periods: int = 1, freq=None, axis=0):
89328932
return self._constructor(new_data).__finalize__(self)
89338933

89348934
def truncate(
8935-
self: FrameOrSeries, before=None, after=None, axis=None, copy: bool_t = True
8936-
) -> FrameOrSeries:
8935+
self: FrameOrSeriesT, before=None, after=None, axis=None, copy: bool_t = True
8936+
) -> FrameOrSeriesT:
89378937
"""
89388938
Truncate a Series or DataFrame before and after some index value.
89398939
@@ -9086,8 +9086,8 @@ def truncate(
90869086
return result
90879087

90889088
def tz_convert(
9089-
self: FrameOrSeries, tz, axis=0, level=None, copy: bool_t = True
9090-
) -> FrameOrSeries:
9089+
self: FrameOrSeriesT, tz, axis=0, level=None, copy: bool_t = True
9090+
) -> FrameOrSeriesT:
90919091
"""
90929092
Convert tz-aware axis to target time zone.
90939093
@@ -9143,14 +9143,14 @@ def _tz_convert(ax, tz):
91439143
return result.__finalize__(self)
91449144

91459145
def tz_localize(
9146-
self: FrameOrSeries,
9146+
self: FrameOrSeriesT,
91479147
tz,
91489148
axis=0,
91499149
level=None,
91509150
copy: bool_t = True,
91519151
ambiguous="raise",
91529152
nonexistent: str = "raise",
9153-
) -> FrameOrSeries:
9153+
) -> FrameOrSeriesT:
91549154
"""
91559155
Localize tz-naive index of a Series or DataFrame to target time zone.
91569156

Diff for: pandas/core/groupby/generic.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import numpy as np
2929

3030
from pandas._libs import Timestamp, lib
31-
from pandas._typing import FrameOrSeries
31+
from pandas._typing import FrameOrSeriesT
3232
from pandas.util._decorators import Appender, Substitution
3333

3434
from pandas.core.dtypes.cast import (
@@ -84,7 +84,7 @@
8484
ScalarResult = typing.TypeVar("ScalarResult")
8585

8686

87-
def generate_property(name: str, klass: Type[FrameOrSeries]):
87+
def generate_property(name: str, klass: Type[FrameOrSeriesT]):
8888
"""
8989
Create a property for a GroupBy subclass to dispatch to DataFrame/Series.
9090
@@ -107,7 +107,7 @@ def prop(self):
107107
return property(prop)
108108

109109

110-
def pin_whitelisted_properties(klass: Type[FrameOrSeries], whitelist: FrozenSet[str]):
110+
def pin_whitelisted_properties(klass: Type[FrameOrSeriesT], whitelist: FrozenSet[str]):
111111
"""
112112
Create GroupBy member defs for DataFrame/Series names in a whitelist.
113113

Diff for: pandas/core/groupby/groupby.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class providing the base-class of operations.
3333

3434
from pandas._libs import Timestamp
3535
import pandas._libs.groupby as libgroupby
36-
from pandas._typing import FrameOrSeries, Scalar
36+
from pandas._typing import FrameOrSeriesT, Scalar
3737
from pandas.compat import set_function_name
3838
from pandas.compat.numpy import function as nv
3939
from pandas.errors import AbstractMethodError
@@ -2439,8 +2439,8 @@ def tail(self, n=5):
24392439
return self._selected_obj[mask]
24402440

24412441
def _reindex_output(
2442-
self, output: FrameOrSeries, fill_value: Scalar = np.NaN
2443-
) -> FrameOrSeries:
2442+
self, output: FrameOrSeriesT, fill_value: Scalar = np.NaN
2443+
) -> FrameOrSeriesT:
24442444
"""
24452445
If we have categorical groupers, then we might want to make sure that
24462446
we have a fully re-indexed output to the levels. This means expanding

Diff for: pandas/core/groupby/grouper.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import numpy as np
99

10-
from pandas._typing import FrameOrSeries
10+
from pandas._typing import FrameOrSeriesT
1111
from pandas.util._decorators import cache_readonly
1212

1313
from pandas.core.dtypes.common import (
@@ -141,7 +141,7 @@ def _get_grouper(self, obj, validate: bool = True):
141141
)
142142
return self.binner, self.grouper, self.obj
143143

144-
def _set_grouper(self, obj: FrameOrSeries, sort: bool = False):
144+
def _set_grouper(self, obj: FrameOrSeriesT, sort: bool = False):
145145
"""
146146
given an object and the specifications, setup the internal grouper
147147
for this particular specification
@@ -244,7 +244,7 @@ def __init__(
244244
self,
245245
index: Index,
246246
grouper=None,
247-
obj: Optional[FrameOrSeries] = None,
247+
obj: Optional[FrameOrSeriesT] = None,
248248
name=None,
249249
level=None,
250250
sort: bool = True,
@@ -424,15 +424,15 @@ def groups(self) -> Dict[Hashable, np.ndarray]:
424424

425425

426426
def get_grouper(
427-
obj: FrameOrSeries,
427+
obj: FrameOrSeriesT,
428428
key=None,
429429
axis: int = 0,
430430
level=None,
431431
sort: bool = True,
432432
observed: bool = False,
433433
mutated: bool = False,
434434
validate: bool = True,
435-
) -> "Tuple[ops.BaseGrouper, List[Hashable], FrameOrSeries]":
435+
) -> "Tuple[ops.BaseGrouper, List[Hashable], FrameOrSeriesT]":
436436
"""
437437
Create and return a BaseGrouper, which is an internal
438438
mapping of how to create the grouper indexers.

Diff for: pandas/core/groupby/ops.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from pandas._libs import NaT, iNaT, lib
1515
import pandas._libs.groupby as libgroupby
1616
import pandas._libs.reduction as libreduction
17-
from pandas._typing import FrameOrSeries
17+
from pandas._typing import FrameOrSeriesT
1818
from pandas.errors import AbstractMethodError
1919
from pandas.util._decorators import cache_readonly
2020

@@ -111,7 +111,7 @@ def __iter__(self):
111111
def nkeys(self) -> int:
112112
return len(self.groupings)
113113

114-
def get_iterator(self, data: FrameOrSeries, axis: int = 0):
114+
def get_iterator(self, data: FrameOrSeriesT, axis: int = 0):
115115
"""
116116
Groupby iterator
117117
@@ -125,7 +125,7 @@ def get_iterator(self, data: FrameOrSeries, axis: int = 0):
125125
for key, (i, group) in zip(keys, splitter):
126126
yield key, group
127127

128-
def _get_splitter(self, data: FrameOrSeries, axis: int = 0) -> "DataSplitter":
128+
def _get_splitter(self, data: FrameOrSeriesT, axis: int = 0) -> "DataSplitter":
129129
comp_ids, _, ngroups = self.group_info
130130
return get_splitter(data, comp_ids, ngroups, axis=axis)
131131

@@ -147,13 +147,13 @@ def _get_group_keys(self):
147147
# provide "flattened" iterator for multi-group setting
148148
return get_flattened_iterator(comp_ids, ngroups, self.levels, self.codes)
149149

150-
def apply(self, f, data: FrameOrSeries, axis: int = 0):
150+
def apply(self, f, data: FrameOrSeriesT, axis: int = 0):
151151
mutated = self.mutated
152152
splitter = self._get_splitter(data, axis=axis)
153153
group_keys = self._get_group_keys()
154154
result_values = None
155155

156-
sdata: FrameOrSeries = splitter._get_sorted_data()
156+
sdata: FrameOrSeriesT = splitter._get_sorted_data()
157157
if sdata.ndim == 2 and np.any(sdata.dtypes.apply(is_extension_array_dtype)):
158158
# calling splitter.fast_apply will raise TypeError via apply_frame_axis0
159159
# if we pass EA instead of ndarray
@@ -754,7 +754,7 @@ def _get_grouper(self):
754754
"""
755755
return self
756756

757-
def get_iterator(self, data: FrameOrSeries, axis: int = 0):
757+
def get_iterator(self, data: FrameOrSeriesT, axis: int = 0):
758758
"""
759759
Groupby iterator
760760
@@ -862,7 +862,7 @@ def _is_indexed_like(obj, axes) -> bool:
862862

863863

864864
class DataSplitter:
865-
def __init__(self, data: FrameOrSeries, labels, ngroups: int, axis: int = 0):
865+
def __init__(self, data: FrameOrSeriesT, labels, ngroups: int, axis: int = 0):
866866
self.data = data
867867
self.labels = ensure_int64(labels)
868868
self.ngroups = ngroups
@@ -893,7 +893,7 @@ def __iter__(self):
893893
for i, (start, end) in enumerate(zip(starts, ends)):
894894
yield i, self._chop(sdata, slice(start, end))
895895

896-
def _get_sorted_data(self) -> FrameOrSeries:
896+
def _get_sorted_data(self) -> FrameOrSeriesT:
897897
return self.data.take(self.sort_idx, axis=self.axis)
898898

899899
def _chop(self, sdata, slice_obj: slice) -> NDFrame:
@@ -920,7 +920,7 @@ def _chop(self, sdata: DataFrame, slice_obj: slice) -> DataFrame:
920920
return sdata._slice(slice_obj, axis=1)
921921

922922

923-
def get_splitter(data: FrameOrSeries, *args, **kwargs) -> DataSplitter:
923+
def get_splitter(data: FrameOrSeriesT, *args, **kwargs) -> DataSplitter:
924924
if isinstance(data, Series):
925925
klass: Type[DataSplitter] = SeriesSplitter
926926
else:

0 commit comments

Comments
 (0)