【问题标题】:Pandas Multi-index slice only on secondary indexPandas 多索引切片仅在二级索引上
【发布时间】:2018-05-20 02:24:30
【问题描述】:

我有以下熊猫(与此处的示例相关: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=0 并获取具有第一个索引的每一行?以下将不起作用:

# In [3]: s.loc[(0),:]

KeyError: 0

我该怎么做呢?

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    jezrael 建议的答案简洁有效。 作为替代方法,您可以像这样使用swaplevel()

    print(s.swaplevel().loc[0, :])
    
    variable
    a    1.534837
    b    1.311133
    c    0.215539
    dtype: float64
    

    【讨论】:

      【解决方案2】:

      使用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)'”
      • 是的,那么首先需要df = df.sort_index()
      • 在文档中是here
      • 我可以在这里问一个与同一个例子非常相关的问题,还是我需要一个新问题
      • 好的,完成。对我来说是一种误解。现在一切都很好。再次感谢
      猜你喜欢
      • 2016-01-16
      • 2016-12-12
      • 2021-08-25
      • 2015-03-16
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-21
      相关资源
      最近更新 更多