4

出于好奇,请轻描淡写地回答这个问题:

我试图查看 MultiIndex 中的切片如何工作时,我遇到了以下情况 ↓</p>

# Simple MultiIndex Creation
index = pd.MultiIndex.from_product([['a', 'c', 'b'], [1, 2]])

# Making Series with that MultiIndex
data = pd.Series(np.random.randint(10, size=6), index=index)

回报:

一个 1 5
   2 0
1 8
   2 6
乙 1 6
   2 3
数据类型:int32

请注意,索引不是按排序顺序,即。a, c, b是在切片时会导致我们想要的预期错误的顺序。

# When we do slicing
data.loc["a":"c"]

像这样的错误:

未排序索引错误

----> 1 个数据.loc["a":"c"]
UnsortedIndexError: '键长度 (1) 大于 MultiIndex lexsort 深度 (0)'

这是预期的。但是现在,在执行以下步骤后:

# Making a DataFrame
data = data.unstack()

# Redindexing - to unsort the indices like before
data = data.reindex(["a", "c", "b"])

# Which looks like 
   1  2
a  5  0
c  8  6
b  6  3

# Then again making series
data = data.stack()

# Reindex Again!
data = data.reindex(["a", "c", "b"], level=0)


# Which looks like before
a  1    5
   2    0
c  1    8
   2    6
b  1    6
   2    3
dtype: int32

问题

所以,现在的流程是:Series → Unstack → DataFrame → Stack → Series

现在,如果我像以前一样进行切片(仍然使用未排序的索引),我们不会收到任何错误!

# The same slicing
data.loc["a":"c"]

结果没有错误:

一个 1 5
   2 0
1 8
   2 6
数据类型:int32

即使data.index.is_monotonicFalse。_ 那我们为什么还要切片呢?

所以问题是:为什么?.

我希望你了解这里的情况。因为看到,在给出错误之前的同一系列,在unstackandstack操作之后没有给出任何错误。

那是我在这里遗漏的错误还是新概念?

谢谢!
阿尤什∞沙阿

更新:我已经使用data.reindex()so 再次取消排序。请再看一遍。

4

1 回答 1

5

您的 2 个数据框之间的区别如下:

index = pd.MultiIndex.from_product([['a', 'c', 'b'], [1, 2]])

data = pd.Series(np.random.randint(10, size=6), index=index)

data2 = data.unstack().reindex(["a", "c", "b"]).stack()

>>> data.index.codes
FrozenList([[0, 0, 2, 2, 1, 1], [0, 1, 0, 1, 0, 1]])

>>> data2.index.codes
FrozenList([[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]])

即使您的两个索引外观(值)相同,内部索引(代码)也不同。

检查MultiIndex方法:

        Create a new MultiIndex from the current to monotonically sorted
        items IN the levels. This does not actually make the entire MultiIndex
        monotonic, JUST the levels.

        The resulting MultiIndex will have the same outward
        appearance, meaning the same .values and ordering. It will also
        be .equals() to the original.

旧答案

# Making a DataFrame
data = data.unstack()

# Which looks like         # <- WRONG
   1  2                    #    1  2
a  5  0                    # a  8  0
c  8  6                    # b  4  1
b  6  3                    # c  7  6

# Then again making series
data = data.stack()

# Which looks like before  # <- WRONG
a  1    5                  # a  1    2
   2    0                  #    2    1
c  1    8                  # b  1    0
   2    6                  #    2    1
b  1    6                  # c  1    3
   2    3                  #    2    9
dtype: int32

如果要使用切片,则必须检查索引是否单调:

# Simple MultiIndex Creation
index = pd.MultiIndex.from_product([['a', 'c', 'b'], [1, 2]])

# Making Series with that MultiIndex
data = pd.Series(np.random.randint(10, size=6), index=index)

>>> data.index.is_monotonic
False

>>> data.unstack().stack().index.is_monotonic
True

>>> data.sort_index().index.is_monotonic
True
于 2021-11-10T08:17:53.857 回答