Skip to content

Fix - BUG: AssertionError when slicing MultiIndex and setting value o… #34973

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 15 additions & 24 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import operator
import warnings
from copy import copy as copy_func
from datetime import datetime
import operator
from textwrap import dedent
from typing import TYPE_CHECKING, Any, Callable, FrozenSet, Hashable, Optional, Union
import warnings

import numpy as np

from pandas._libs import algos as libalgos, index as libindex, lib
import pandas._libs.join as libjoin
from pandas._libs.lib import is_datetime_array, no_default
from pandas._libs.tslibs import OutOfBoundsDatetime, Timestamp
from pandas._libs.tslibs.period import IncompatibleFrequency
from pandas._libs.tslibs.timezones import tz_compare

import pandas.core.algorithms as algos
import pandas.core.common as com
import pandas.core.missing as missing
from pandas._libs import algos as libalgos, index as libindex, lib
from pandas._libs.tslibs import OutOfBoundsDatetime, Timestamp
from pandas._typing import DtypeObj, Label
from pandas.compat import set_function_name
from pandas.compat.numpy import function as nv
from pandas.errors import InvalidIndexError
from pandas.util._decorators import Appender, Substitution, cache_readonly, doc

from pandas.core import ops
from pandas.core.accessor import CachedAccessor
from pandas.core.arrays import Categorical, ExtensionArray
from pandas.core.arrays.datetimes import tz_to_dtype, validate_tz_from_dtype
from pandas.core.base import IndexOpsMixin, PandasObject
from pandas.core.dtypes import concat as _concat
from pandas.core.dtypes.cast import (
maybe_cast_to_integer_array,
Expand Down Expand Up @@ -63,29 +68,21 @@
ABCTimedeltaIndex,
)
from pandas.core.dtypes.missing import array_equivalent, isna

from pandas.core import ops
from pandas.core.accessor import CachedAccessor
import pandas.core.algorithms as algos
from pandas.core.arrays import Categorical, ExtensionArray
from pandas.core.arrays.datetimes import tz_to_dtype, validate_tz_from_dtype
from pandas.core.base import IndexOpsMixin, PandasObject
import pandas.core.common as com
from pandas.core.indexers import deprecate_ndim_indexing
from pandas.core.indexes.frozen import FrozenList
import pandas.core.missing as missing
from pandas.core.ops import get_op_result_name
from pandas.core.ops.invalid import make_invalid_op
from pandas.core.sorting import ensure_key_mapped
from pandas.core.strings import StringMethods

from pandas.errors import InvalidIndexError
from pandas.io.formats.printing import (
PrettyDict,
default_pprint,
format_object_attrs,
format_object_summary,
pprint_thing,
)
from pandas.util._decorators import Appender, Substitution, cache_readonly, doc

if TYPE_CHECKING:
from pandas import Series
Expand Down Expand Up @@ -4946,12 +4943,6 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None):
"""
start_slice, end_slice = self.slice_locs(start, end, step=step, kind=kind)

# return a slice
if not is_scalar(start_slice):
raise AssertionError("Start slice bound is non-scalar")
if not is_scalar(end_slice):
raise AssertionError("End slice bound is non-scalar")

return slice(start_slice, end_slice, step)

def _maybe_cast_indexer(self, key):
Expand Down
6 changes: 5 additions & 1 deletion pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2890,7 +2890,11 @@ def convert_indexer(start, stop, step, indexer=indexer, codes=level_codes):
# if we have a provided indexer, then this need not consider
# the entire labels set

r = np.arange(start, stop, step)
if is_scalar(start) and is_scalar(stop):
r = np.arange(start, stop, step)
else:
r = np.all(start, stop, step)

if indexer is not None and len(indexer) != len(codes):

# we have an indexer which maps the locations in the labels
Expand Down
16 changes: 16 additions & 0 deletions pandas/tests/indexing/test_loc.py
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,22 @@ def test_loc_reverse_assignment(self):

tm.assert_series_equal(result, expected)

def test_loc_setting_value_at_multiindex(self):
# GH 34870
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
array = [1, 1, 1, 1, 1, 1, 1, 1]
answer = [1, 1, 100, 100, 100, 100, 1, 1]

tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

dt1 = pd.Series(array, index=index)
dt2 = pd.Series(answer, index=index)

dt1.loc[('baz', 'one'):('foo', 'two')] = 100
tm.assert_series_equal(dt1, dt2)


def test_series_loc_getitem_label_list_missing_values():
# gh-11428
Expand Down