# Buggy code
def apply_func_to_select_indices(self, axis, func, indices, keep_remaining=False):
    """Applies a function to select indices.

    Note: Your internal function must take a kwarg `internal_indices` for
        this to work correctly. This prevents information leakage of the
        internal index to the external representation.

    Args:
        axis: The axis to apply the func over.
        func: The function to apply to these indices.
        indices: The indices to apply the function to.
        keep_remaining: Whether or not to keep the other partitions.
            Some operations may want to drop the remaining partitions and
            keep only the results.

    Returns:
        A new BaseBlockPartitions object, the type of object that called this.
    """
    # Handling dictionaries has to be done differently, but we still want
    # to figure out the partitions that need to be applied to, so we will
    # store the dictionary in a separate variable and assign `indices` to
    # the keys to handle it the same as we normally would.
    if isinstance(indices, dict):
        dict_indices = indices
        indices = list(indices.keys())
    else:
        dict_indices = None
    if not isinstance(indices, list):
        indices = [indices]
    partitions_dict = self._get_dict_of_block_index(
        axis, indices, ordered=not keep_remaining
    )
    if not axis:
        partitions_for_apply = self.partitions.T
    else:
        partitions_for_apply = self.partitions
    # We may have a command to perform different functions on different
    # columns at the same time. We attempt to handle this as efficiently as
    # possible here. Functions that use this in the dictionary format must
    # accept a keyword argument `func_dict`.
    if dict_indices is not None:

        def local_to_global_idx(partition_id, local_idx):
            if partition_id == 0:
                return local_idx
            if axis == 0:
                cumulative_axis = np.cumsum(self.block_widths)
            else:
                cumulative_axis = np.cumsum(self.block_lengths)
            return cumulative_axis[partition_id - 1] + local_idx

        if not keep_remaining:
            result = np.array(
                [
                    self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[o_idx],
                        func_dict={
                            i_idx: dict_indices[local_to_global_idx(o_idx, i_idx)]
                            for i_idx in list_to_apply
                            if i_idx >= 0
                        },
                    )
                    for o_idx, list_to_apply in partitions_dict
                ]
            )
        else:
            result = np.array(
                [
                    partitions_for_apply[i]
                    if i not in partitions_dict
                    else self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[i],
                        func_dict={
                            idx: dict_indices[local_to_global_idx(i, idx)]
                            for idx in partitions_dict[i]
                            if idx >= 0
                        },
                    )
                    for i in range(len(partitions_for_apply))
                ]
            )
    else:
        if not keep_remaining:
            # We are passing internal indices in here. In order for func to
            # actually be able to use this information, it must be able to take in
            # the internal indices. This might mean an iloc in the case of Pandas
            # or some other way to index into the internal representation.
            result = np.array(
                [
                    self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[idx],
                        internal_indices=list_to_apply,
                    )
                    for idx, list_to_apply in partitions_dict
                ]
            )
        else:
            # The difference here is that we modify a subset and return the
            # remaining (non-updated) blocks in their original position.
            result = np.array(
                [
                    partitions_for_apply[i]
                    if i not in partitions_dict
                    else self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[i],
                        internal_indices=partitions_dict[i],
                    )
                    for i in range(len(partitions_for_apply))
                ]
            )
    return self.__constructor__(result.T) if not axis else self.__constructor__(result)


# Traceback (Exception)
Exception                                 Traceback (most recent call last)
~/Downloads/kaggle5/kaggle5.py in <module>
161         for j in range(0, 3):
162             try:
--> 163                 guess_df = dataset[(dataset['Sex'] == i) &amp; (dataset['Pclass'] == j+1)]['Age'].dropna()
164             except:
165                 print(dataset[(dataset['Sex'] == i) &amp; (dataset['Pclass'] == j+1)])

~/software_builds/modin/modin/pandas/dataframe.py in __getitem__(self, key)
4504         try:
4505             if key in self.columns and not is_mi_columns:
-> 4506                 return self._getitem_column(key)
4507         except (KeyError, ValueError, TypeError):
4508             pass

~/software_builds/modin/modin/pandas/dataframe.py in _getitem_column(self, key)
4524     def _getitem_column(self, key):
4525         return SeriesView(
-> 4526             self._query_compiler.getitem_single_key(key), self, (slice(None), key)
4527         )
4528

~/software_builds/modin/modin/data_management/query_compiler/pandas_query_compiler.py in getitem_single_key(self, key)
2165             A new PandasDataManager.
2166         """
-> 2167         new_data = self.getitem_column_array([key])
2168         if len(self.columns.get_indexer_for([key])) > 1:
2169             return new_data

~/software_builds/modin/modin/data_management/query_compiler/pandas_query_compiler.py in getitem_column_array(self, key)
2192
2193         result = self.data.apply_func_to_select_indices(
-> 2194             0, getitem, numeric_indices, keep_remaining=False
2195         )
2196         # We can't just set the columns to key here because there may be

~/software_builds/modin/modin/engines/base/block_partitions.py in apply_func_to_select_indices(self, axis, func, indices, keep_remaining)
707             indices = [indices]
708         partitions_dict = self._get_dict_of_block_index(
--> 709             axis, indices, ordered=not keep_remaining
710         )
711         if not axis:

~/software_builds/modin/modin/engines/base/block_partitions.py in _get_dict_of_block_index(self, axis, indices, ordered)
631         # travel to each partition once.
632         all_partitions_and_idx = [
--> 633             self._get_blocks_containing_index(axis, i) for i in indices
634         ]
635

~/software_builds/modin/modin/engines/base/block_partitions.py in <listcomp>(.0)
631         # travel to each partition once.
632         all_partitions_and_idx = [
--> 633             self._get_blocks_containing_index(axis, i) for i in indices
634         ]
635

~/software_builds/modin/modin/engines/base/block_partitions.py in _get_blocks_containing_index(self, axis, index)
588         """
589         if not axis:
--> 590             ErrorMessage.catch_bugs_and_request_email(index > sum(self.block_widths))
591             cumulative_column_widths = np.array(self.block_widths).cumsum()
592             block_idx = int(np.digitize(index, cumulative_column_widths))

~/software_builds/modin/modin/error_message.py in catch_bugs_and_request_email(cls, failure_condition)
25         if failure_condition:
26             raise Exception(
---> 27                 "Internal Error. "
28                 "Please email bugs@modin.org with the traceback and command that "
29                 "caused this error."

Exception: Internal Error. Please email bugs@modin.org with the traceback and command that caused this error.

# Fixed code
def apply_func_to_select_indices(self, axis, func, indices, keep_remaining=False):
    """Applies a function to select indices.

    Note: Your internal function must take a kwarg `internal_indices` for
        this to work correctly. This prevents information leakage of the
        internal index to the external representation.

    Args:
        axis: The axis to apply the func over.
        func: The function to apply to these indices.
        indices: The indices to apply the function to.
        keep_remaining: Whether or not to keep the other partitions.
            Some operations may want to drop the remaining partitions and
            keep only the results.

    Returns:
        A new BaseBlockPartitions object, the type of object that called this.
    """
    if self.partitions.size == 0:
        return np.array([[]])
    # Handling dictionaries has to be done differently, but we still want
    # to figure out the partitions that need to be applied to, so we will
    # store the dictionary in a separate variable and assign `indices` to
    # the keys to handle it the same as we normally would.
    if isinstance(indices, dict):
        dict_indices = indices
        indices = list(indices.keys())
    else:
        dict_indices = None
    if not isinstance(indices, list):
        indices = [indices]
    partitions_dict = self._get_dict_of_block_index(
        axis, indices, ordered=not keep_remaining
    )
    if not axis:
        partitions_for_apply = self.partitions.T
    else:
        partitions_for_apply = self.partitions
    # We may have a command to perform different functions on different
    # columns at the same time. We attempt to handle this as efficiently as
    # possible here. Functions that use this in the dictionary format must
    # accept a keyword argument `func_dict`.
    if dict_indices is not None:

        def local_to_global_idx(partition_id, local_idx):
            if partition_id == 0:
                return local_idx
            if axis == 0:
                cumulative_axis = np.cumsum(self.block_widths)
            else:
                cumulative_axis = np.cumsum(self.block_lengths)
            return cumulative_axis[partition_id - 1] + local_idx

        if not keep_remaining:
            result = np.array(
                [
                    self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[o_idx],
                        func_dict={
                            i_idx: dict_indices[local_to_global_idx(o_idx, i_idx)]
                            for i_idx in list_to_apply
                            if i_idx >= 0
                        },
                    )
                    for o_idx, list_to_apply in partitions_dict
                ]
            )
        else:
            result = np.array(
                [
                    partitions_for_apply[i]
                    if i not in partitions_dict
                    else self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[i],
                        func_dict={
                            idx: dict_indices[local_to_global_idx(i, idx)]
                            for idx in partitions_dict[i]
                            if idx >= 0
                        },
                    )
                    for i in range(len(partitions_for_apply))
                ]
            )
    else:
        if not keep_remaining:
            # We are passing internal indices in here. In order for func to
            # actually be able to use this information, it must be able to take in
            # the internal indices. This might mean an iloc in the case of Pandas
            # or some other way to index into the internal representation.
            result = np.array(
                [
                    self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[idx],
                        internal_indices=list_to_apply,
                    )
                    for idx, list_to_apply in partitions_dict
                ]
            )
        else:
            # The difference here is that we modify a subset and return the
            # remaining (non-updated) blocks in their original position.
            result = np.array(
                [
                    partitions_for_apply[i]
                    if i not in partitions_dict
                    else self._apply_func_to_list_of_partitions(
                        func,
                        partitions_for_apply[i],
                        internal_indices=partitions_dict[i],
                    )
                    for i in range(len(partitions_for_apply))
                ]
            )
    return self.__constructor__(result.T) if not axis else self.__constructor__(result)