-
Notifications
You must be signed in to change notification settings - Fork 116
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
SNOW-1661142 Fix index name behavior #2274
Changes from 11 commits
125f86d
299f33a
41e69e2
6e00c73
21dbccb
34f0e50
ab5656f
86c7310
bb6242b
9a1bce4
807b769
a70f20c
2f6dcf3
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 |
---|---|---|
|
@@ -71,6 +71,35 @@ | |
} | ||
|
||
|
||
class IndexParent: | ||
def __init__(self, parent: DataFrame | Series) -> None: | ||
""" | ||
Initialize the IndexParent object. | ||
|
||
IndexParent is used to keep track of the parent object that the Index is a part of. | ||
It tracks the parent object and the parent object's query compiler at the time of creation. | ||
|
||
Parameters | ||
---------- | ||
parent : DataFrame or Series | ||
The parent object that the Index is a part of. | ||
""" | ||
assert isinstance(parent, (DataFrame, Series)) | ||
self._parent = parent | ||
self._parent_qc = parent._query_compiler | ||
|
||
def check_and_update_parent_qc_index_names(self, names: list) -> None: | ||
""" | ||
Update the Index and its parent's index names if the parent's current query compiler matches | ||
the recorded query compiler (`_parent_qc`). | ||
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. add a comment here that "if the query compiler associated with parent is not the same as the original recorded one that means an inplace updates have been applied to the parent" 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. done! |
||
""" | ||
if self._parent._query_compiler is self._parent_qc: | ||
new_query_compiler = self._parent_qc.set_index_names(names) | ||
self._parent._update_inplace(new_query_compiler=new_query_compiler) | ||
# Update the query compiler after naming operation. | ||
self._parent_qc = new_query_compiler | ||
|
||
|
||
class Index(metaclass=TelemetryMeta): | ||
|
||
# Equivalent index type in native pandas | ||
|
@@ -135,7 +164,7 @@ def __new__( | |
index = object.__new__(cls) | ||
# Initialize the Index | ||
index._query_compiler = query_compiler | ||
# `_parent` keeps track of any Series or DataFrame that this Index is a part of. | ||
# `_parent` keeps track of the parent object that this Index is a part of. | ||
index._parent = None | ||
return index | ||
|
||
|
@@ -252,6 +281,17 @@ def __getattr__(self, key: str) -> Any: | |
ErrorMessage.not_implemented(f"Index.{key} is not yet implemented") | ||
raise err | ||
|
||
def _set_parent(self, parent: Series | DataFrame) -> None: | ||
""" | ||
Set the parent object and its query compiler. | ||
|
||
Parameters | ||
---------- | ||
parent : Series or DataFrame | ||
The parent object that the Index is a part of. | ||
""" | ||
self._parent = IndexParent(parent) | ||
|
||
def _binary_ops(self, method: str, other: Any) -> Index: | ||
if isinstance(other, Index): | ||
other = other.to_series().reset_index(drop=True) | ||
|
@@ -408,12 +448,6 @@ def __constructor__(self): | |
""" | ||
return type(self) | ||
|
||
def _set_parent(self, parent: Series | DataFrame): | ||
""" | ||
Set the parent object of the current Index to a given Series or DataFrame. | ||
""" | ||
self._parent = parent | ||
|
||
@property | ||
def values(self) -> ArrayLike: | ||
""" | ||
|
@@ -726,10 +760,10 @@ def name(self, value: Hashable) -> None: | |
if not is_hashable(value): | ||
raise TypeError(f"{type(self).__name__}.name must be a hashable type") | ||
self._query_compiler = self._query_compiler.set_index_names([value]) | ||
# Update the name of the parent's index only if the parent's current query compiler | ||
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. can you update the doc for the name function to make it clear that the inplace replacement only works when no inplace update has been applied to parent 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. done! |
||
# matches the recorded query compiler. | ||
if self._parent is not None: | ||
self._parent._update_inplace( | ||
new_query_compiler=self._parent._query_compiler.set_index_names([value]) | ||
) | ||
self._parent.check_and_update_parent_qc_index_names([value]) | ||
|
||
def _get_names(self) -> list[Hashable]: | ||
""" | ||
|
@@ -755,10 +789,10 @@ def _set_names(self, values: list) -> None: | |
if isinstance(values, Index): | ||
values = values.to_list() | ||
self._query_compiler = self._query_compiler.set_index_names(values) | ||
# Update the name of the parent's index only if the parent's current query compiler | ||
# matches the recorded query compiler. | ||
if self._parent is not None: | ||
self._parent._update_inplace( | ||
new_query_compiler=self._parent._query_compiler.set_index_names(values) | ||
) | ||
self._parent.check_and_update_parent_qc_index_names(values) | ||
|
||
names = property(fset=_set_names, fget=_get_names) | ||
|
||
|
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.
"index name when it is not supposed to." -> index name after an inplace updates have been applied to the original series/dataframe
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.
done!