-
-
Notifications
You must be signed in to change notification settings - Fork 19.1k
Separate MultiIndex names from levels #27242
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 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -274,6 +274,7 @@ def __new__( | |
result._set_levels(levels, copy=copy, validate=False) | ||
result._set_codes(codes, copy=copy, validate=False) | ||
|
||
result._names = [None for _ in levels] | ||
|
||
if names is not None: | ||
# handles name validation | ||
result._set_names(names) | ||
|
@@ -1216,7 +1217,7 @@ def __len__(self): | |
return len(self.codes[0]) | ||
|
||
def _get_names(self): | ||
return FrozenList(level.name for level in self.levels) | ||
return FrozenList(self._names) | ||
|
||
def _set_names(self, names, level=None, validate=True): | ||
""" | ||
|
@@ -1262,7 +1263,7 @@ def _set_names(self, names, level=None, validate=True): | |
level = [self._get_level_number(l) for l in level] | ||
|
||
# set the name | ||
for l, name in zip(level, names): | ||
for lev, name in zip(level, names): | ||
if name is not None: | ||
# GH 20527 | ||
# All items in 'names' need to be hashable: | ||
|
@@ -1272,7 +1273,7 @@ def _set_names(self, names, level=None, validate=True): | |
self.__class__.__name__ | ||
) | ||
) | ||
self.levels[l].rename(name, inplace=True) | ||
self._names[lev] = name | ||
|
||
names = property( | ||
fset=_set_names, fget=_get_names, doc="""\nNames of levels in MultiIndex.\n""" | ||
|
@@ -1582,13 +1583,13 @@ def _get_level_values(self, level, unique=False): | |
values : ndarray | ||
""" | ||
|
||
values = self.levels[level] | ||
lev = self.levels[level] | ||
level_codes = self.codes[level] | ||
name = self._names[level] | ||
if unique: | ||
level_codes = algos.unique(level_codes) | ||
filled = algos.take_1d(values._values, level_codes, fill_value=values._na_value) | ||
values = values._shallow_copy(filled) | ||
return values | ||
filled = algos.take_1d(lev._values, level_codes, fill_value=lev._na_value) | ||
return lev._shallow_copy(filled, name=name) | ||
|
||
def get_level_values(self, level): | ||
""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -259,10 +259,13 @@ def get_new_values(self): | |
def get_new_columns(self): | ||
if self.value_columns is None: | ||
if self.lift == 0: | ||
return self.removed_level | ||
lev = self.removed_level._shallow_copy() | ||
|
||
lev.name = self.removed_name | ||
return lev | ||
|
||
lev = self.removed_level | ||
return lev.insert(0, lev._na_value) | ||
lev = self.removed_level.insert(0, item=self.removed_level._na_value) | ||
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. I would use .rename() |
||
lev.name = self.removed_name | ||
return lev | ||
|
||
stride = len(self.removed_level) + self.lift | ||
width = len(self.value_columns) | ||
|
@@ -301,7 +304,9 @@ def get_new_index(self): | |
lev, lab = self.new_index_levels[0], result_codes[0] | ||
if (lab == -1).any(): | ||
lev = lev.insert(len(lev), lev._na_value) | ||
return lev.take(lab) | ||
new_index = lev.take(lab) | ||
|
||
new_index.name = self.new_index_names[0] | ||
return new_index | ||
|
||
return MultiIndex( | ||
levels=self.new_index_levels, | ||
|
@@ -661,7 +666,9 @@ def _convert_level_number(level_num, columns): | |
new_names = this.columns.names[:-1] | ||
new_columns = MultiIndex.from_tuples(unique_groups, names=new_names) | ||
else: | ||
new_columns = unique_groups = this.columns.levels[0] | ||
new_columns = this.columns.levels[0]._shallow_copy() | ||
|
||
new_columns.name = this.columns.names[0] | ||
unique_groups = new_columns | ||
|
||
# time to ravel the values | ||
new_data = {} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -978,7 +978,7 @@ def test_reset_index(self, float_frame): | |
): | ||
values = lev.take(level_codes) | ||
name = names[i] | ||
tm.assert_index_equal(values, Index(deleveled[name])) | ||
tm.assert_index_equal(values, Index(deleveled[name]), check_names=False) | ||
|
||
|
||
stacked.index.names = [None, None] | ||
deleveled2 = stacked.reset_index() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -335,7 +335,7 @@ def test_count_level_corner(self): | |
df = self.frame[:0] | ||
result = df.count(level=0) | ||
expected = ( | ||
DataFrame(index=s.index.levels[0], columns=df.columns) | ||
DataFrame(index=s.index.levels[0].set_names(["first"]), columns=df.columns) | ||
.fillna(0) | ||
.astype(np.int64) | ||
) | ||
|
@@ -976,13 +976,11 @@ def test_count(self): | |
|
||
result = series.count(level="b") | ||
expect = self.series.count(level=1) | ||
tm.assert_series_equal(result, expect, check_names=False) | ||
assert result.index.name == "b" | ||
tm.assert_series_equal(result, expect) | ||
|
||
result = series.count(level="a") | ||
expect = self.series.count(level=0) | ||
tm.assert_series_equal(result, expect, check_names=False) | ||
assert result.index.name == "a" | ||
tm.assert_series_equal(result, expect) | ||
|
||
msg = "Level x not found" | ||
with pytest.raises(KeyError, match=msg): | ||
|
@@ -1036,10 +1034,10 @@ def aggf(x): | |
# for good measure, groupby detail | ||
level_index = frame._get_axis(axis).levels[level] | ||
|
||
tm.assert_index_equal(leftside._get_axis(axis), level_index) | ||
tm.assert_index_equal(rightside._get_axis(axis), level_index) | ||
tm.assert_index_equal(leftside._get_axis(axis), level_index, check_names=False) | ||
tm.assert_index_equal(rightside._get_axis(axis), level_index, check_names=False) | ||
|
||
tm.assert_frame_equal(leftside, rightside) | ||
tm.assert_frame_equal(leftside, rightside, check_names=False) | ||
|
||
def test_stat_op_corner(self): | ||
obj = Series([10.0], index=MultiIndex.from_tuples([(2, 3)])) | ||
|
@@ -1639,12 +1637,12 @@ def test_constructor_with_tz(self): | |
) | ||
|
||
result = MultiIndex.from_arrays([index, columns]) | ||
tm.assert_index_equal(result.levels[0], index) | ||
tm.assert_index_equal(result.levels[1], columns) | ||
tm.assert_index_equal(result.levels[0], index, check_names=False) | ||
|
||
tm.assert_index_equal(result.levels[1], columns, check_names=False) | ||
|
||
result = MultiIndex.from_arrays([Series(index), Series(columns)]) | ||
tm.assert_index_equal(result.levels[0], index) | ||
tm.assert_index_equal(result.levels[1], columns) | ||
tm.assert_index_equal(result.levels[0], index, check_names=False) | ||
tm.assert_index_equal(result.levels[1], columns, check_names=False) | ||
|
||
def test_set_index_datetime(self): | ||
# GH 3950 | ||
|
@@ -1672,12 +1670,14 @@ def test_set_index_datetime(self): | |
expected = expected.tz_localize("UTC").tz_convert("US/Pacific") | ||
|
||
df = df.set_index("label", append=True) | ||
tm.assert_index_equal(df.index.levels[0], expected) | ||
tm.assert_index_equal(df.index.levels[1], Index(["a", "b"], name="label")) | ||
tm.assert_index_equal(df.index.levels[0], expected, check_names=False) | ||
tm.assert_index_equal(df.index.levels[1], Index(["a", "b"])) | ||
assert df.index.names == ["datetime", "label"] | ||
|
||
df = df.swaplevel(0, 1) | ||
tm.assert_index_equal(df.index.levels[0], Index(["a", "b"], name="label")) | ||
tm.assert_index_equal(df.index.levels[1], expected) | ||
tm.assert_index_equal(df.index.levels[0], Index(["a", "b"])) | ||
tm.assert_index_equal(df.index.levels[1], expected, check_names=False) | ||
assert df.index.names == ["label", "datetime"] | ||
|
||
df = DataFrame(np.random.random(6)) | ||
idx1 = pd.DatetimeIndex( | ||
|
Uh oh!
There was an error while loading. Please reload this page.