Pandas多级索引仅在次级索引上进行切片

4
我有以下的pandas数据(与这里的示例相关:pandas: slice a MultiIndex by range of secondary index
import numpy as np
import pandas as pd

variable = np.repeat(['a','b','c'], [5,5,5])
time = [0,1,5,10,20,0,1,5,10,20,0,1,5,10,20]

arra = [variable, time]

index=pd.MultiIndex.from_arrays(arra, names=("variable", "time"))

s = pd.Series(
    np.random.randn(len(sequence)), 
    index=index
)

输出将会是:

# In [1]: s
variable  time
a         0      -1.284692
          1      -0.313895
          5      -0.980222
          10     -1.452306
          20     -0.423921
b         0       0.248625
          1       0.183721
          5      -0.733377
          10      1.562653
          20     -1.092559
c         0       0.061172
          1       0.133960
          5       0.765271
          10     -0.648834
          20      0.147158
dtype: float64

如果我在这两个多重索引上切片,它会像这样工作:
# In [2]: s.loc[("a",0),:]
variable  time
a         0       1.583589
          1      -1.081401
          5      -0.497904
          10      0.352880
          20     -0.179062
dtype: float64

但是我怎样才能仅仅在二级索引"time"上切片,例如在time=0时获取每一行的第一个索引?以下方法行不通:
# In [3]: s.loc[(0),:]

KeyError: 0

我应该在这里怎么做?


2个回答

7

使用xs方法,指定第二级别进行选择,或者使用带有:loc方法选择第一级别的所有值,使用0选择第二级别的值:

print (s.xs(0, level=1))

或者:

print (s.loc[:, 0])


a    0.376784
b   -0.643836
c   -0.440340
dtype: float64

如果要使用DataFrame的索引和列,请使用slicers: (参考链接)
idx = pd.IndexSlice
df = pd.concat([s,s * 10], axis=1, keys=['a','b'])
print (df)
                      a          b
variable time                     
a        0     1.054582  10.545820
         1    -1.716213 -17.162130
         5    -0.187765  -1.877645
         10   -0.419005  -4.190047
         20   -0.772808  -7.728078
b        0    -0.022520  -0.225202
         1    -0.638453  -6.384531
         5     0.410156   4.101559
         10    0.512189   5.121889
         20   -1.241232 -12.412322
c        0    -0.134815  -1.348148
         1    -1.007632 -10.076318
         5    -0.859790  -8.597898
         10   -0.623177  -6.231767
         20   -0.635504  -6.355036

print (df.loc[idx[:, 0], 'a'])
variable  time
a         0       1.054582
b         0      -0.022520
c         0      -0.134815
Name: a, dtype: float64

太好了,".xs"现在可以使用了。我正在尝试将解决方案应用到我的真实数据框中,但我想选择/保留除"a"以外的所有列。只保留逗号会导致"UnsortedIndexError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (2), lexsort depth (1)'"。 - Rockbar
是的,那么需要先执行 df = df.sort_index() - jezrael
文档在这里:http://pandas.pydata.org/pandas-docs/stable/advanced.html#sorting-a-multiindex - jezrael
我可以在这里问一个非常相关的问题吗,还是需要一个新的问题? - Rockbar
我现在离线了,只能用手机,建议您提一个新问题。 - jezrael
1
好的,完成了。那是我误解了。现在一切都好了。再次感谢。 - Rockbar

1
jezrael 提供的答案简洁明了并且可行。作为替代方案,你可以像这样使用 swaplevel()
print(s.swaplevel().loc[0, :])

variable
a    1.534837
b    1.311133
c    0.215539
dtype: float64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接