-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Reduce Circular Imports with pandas.core.reshape.concat #29133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ba50ba7
6fe04dd
33d75ca
ee04957
230cf5f
5fc32cc
f61baec
2a00f64
56229f6
0448910
6e76bfc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,14 +6,16 @@ | |
|
||
import numpy as np | ||
|
||
from pandas import DataFrame, Index, MultiIndex, Series | ||
from pandas.core.dtypes.generic import ABCDataFrame, ABCSeries | ||
|
||
from pandas.core import common as com | ||
from pandas.core.arrays.categorical import ( | ||
_factorize_from_iterable, | ||
_factorize_from_iterables, | ||
) | ||
from pandas.core.generic import NDFrame | ||
from pandas.core.index import ( | ||
Index, | ||
MultiIndex, | ||
_all_indexes_same, | ||
_get_consensus_names, | ||
_get_objs_combined_axis, | ||
|
@@ -275,7 +277,7 @@ def __init__( | |
copy=True, | ||
sort=False, | ||
): | ||
if isinstance(objs, (NDFrame, str)): | ||
if isinstance(objs, (ABCDataFrame, ABCSeries, str)): | ||
raise TypeError( | ||
"first argument must be an iterable of pandas " | ||
"objects, you passed an object of type " | ||
|
@@ -322,7 +324,7 @@ def __init__( | |
# consolidate data & figure out what our result ndim is going to be | ||
ndims = set() | ||
for obj in objs: | ||
if not isinstance(obj, (Series, DataFrame)): | ||
if not isinstance(obj, (ABCSeries, ABCDataFrame)): | ||
msg = ( | ||
"cannot concatenate object of type '{}';" | ||
" only Series and DataFrame objs are valid".format(type(obj)) | ||
|
@@ -348,7 +350,7 @@ def __init__( | |
# filter out the empties if we have not multi-index possibilities | ||
# note to keep empty Series as it affect to result columns / name | ||
non_empties = [ | ||
obj for obj in objs if sum(obj.shape) > 0 or isinstance(obj, Series) | ||
obj for obj in objs if sum(obj.shape) > 0 or isinstance(obj, ABCSeries) | ||
] | ||
|
||
if len(non_empties) and ( | ||
|
@@ -362,17 +364,26 @@ def __init__( | |
self.objs = objs | ||
|
||
# Standardize axis parameter to int | ||
if isinstance(sample, Series): | ||
# TODO: Should this really require a class import? | ||
""" | ||
if isinstance(sample, ABCSeries): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is maybe a relic of the old panel days but as of now it seems a little overkill to import the generic class definition to resolve "index" and "columns" to their respective axis numbers. For now I just did this in the function body directly below commented code, but this probably belongs somewhere else as a utility function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my intuition is that you're right here. A lot of _axis_reversed stuff feels leftover |
||
axis = DataFrame._get_axis_number(axis) | ||
else: | ||
axis = sample._get_axis_number(axis) | ||
""" | ||
# TODO: implement universal axis validation; align with core.generic | ||
if not isinstance(axis, int): | ||
try: | ||
axis = {"index": 0, "rows": 0, "columns": 1}[axis] | ||
except KeyError: | ||
raise ValueError("No axis named {}".format(axis)) | ||
|
||
# Need to flip BlockManager axis in the DataFrame special case | ||
self._is_frame = isinstance(sample, DataFrame) | ||
self._is_frame = isinstance(sample, ABCDataFrame) | ||
if self._is_frame: | ||
axis = 1 if axis == 0 else 0 | ||
|
||
self._is_series = isinstance(sample, Series) | ||
self._is_series = isinstance(sample, ABCSeries) | ||
if not 0 <= axis <= sample.ndim: | ||
raise AssertionError( | ||
"axis must be between 0 and {ndim}, input was" | ||
|
@@ -545,7 +556,7 @@ def _get_concat_axis(self): | |
num = 0 | ||
has_names = False | ||
for i, x in enumerate(self.objs): | ||
if not isinstance(x, Series): | ||
if not isinstance(x, ABCSeries): | ||
raise TypeError( | ||
"Cannot concatenate type 'Series' " | ||
"with object of type {type!r}".format(type=type(x).__name__) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can the
merge
import also be moved up?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was hoping so but doesn't appear to be the case. I think its intertwined with some of the Categorical stuff so might make sense if / when I can resolve that space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great.
Categorical is used in a lot of places where I think/hope a less high-powered tool could be used, and doing so couple simplify the dependency structure of the code base quite a bit.