36

次のような MultiIndex を持つシリーズがあります。

import numpy as np
import pandas as pd

buckets = np.repeat(['a','b','c'], [3,5,1])
sequence = [0,1,5,0,1,2,4,50,0]

s = pd.Series(
    np.random.randn(len(sequence)), 
    index=pd.MultiIndex.from_tuples(zip(buckets, sequence))
)

# In [6]: s
# Out[6]: 
# a  0    -1.106047
#    1     1.665214
#    5     0.279190
# b  0     0.326364
#    1     0.900439
#    2    -0.653940
#    4     0.082270
#    50   -0.255482
# c  0    -0.091730

sequence2 番目のインデックス (' ') が 2 から 10 の間の s['b'] 値を取得したいと思います。

最初のインデックスでのスライスはうまくいきます:

s['a':'b']
# Out[109]: 
# bucket  value
# a       0        1.828176
#         1        0.160496
#         5        0.401985
# b       0       -1.514268
#         1       -0.973915
#         2        1.285553
#         4       -0.194625
#         5       -0.144112

しかし、少なくとも2つの最も明白な方法と思われるものによって、2番目ではありません。

1) これは、インデックス値とは関係なく、要素 1 から 4 を返します

s['b'][1:10]

# In [61]: s['b'][1:10]
# Out[61]: 
# 1     0.900439
# 2    -0.653940
# 4     0.082270
# 50   -0.255482

ただし、インデックスを逆にして、最初のインデックスが整数で、2 番目のインデックスが文字列の場合、次のように動作します。

In [26]: s
Out[26]: 
0   a   -0.126299
1   a    1.810928
5   a    0.571873
0   b   -0.116108
1   b   -0.712184
2   b   -1.771264
4   b    0.148961
50  b    0.089683
0   c   -0.582578

In [25]: s[0]['a':'b']
Out[25]: 
a   -0.126299
b   -0.116108
4

5 に答える 5

38

Robbie-Clarken が答えているように、0.14 以降、loc に渡すタプルにスライスを渡すことができます。

In [11]: s.loc[('b', slice(2, 10))]
Out[11]:
b  2   -0.65394
   4    0.08227
dtype: float64

実際、各レベルにスライスを渡すことができます:

In [12]: s.loc[(slice('a', 'b'), slice(2, 10))]
Out[12]:
a  5    0.27919
b  2   -0.65394
   4    0.08227
dtype: float64

注: スライスは包括的です。


古い答え:

以下を使用してこれを行うこともできます。

s.ix[1:10, "b"]

(このバージョンでは割り当てが許可されているため、単一の ix/loc/iloc で行うことをお勧めします。)

この回答は、2013 年初頭に ilocが導入される前に書かれたものです。つまり、位置/整数の場所です。この場合は、これが優先される可能性があります。これが作成された理由は、整数インデックスの pandas オブジェクトからあいまいさを取り除き、より説明的にすることでした:「私は位置をスライスしています」.

s["b"].iloc[1:10]

そうは言っても、私は ix が次のようなドキュメントには同意しません:

最も堅牢で一貫した方法

そうではありません。最も一貫した方法は、何をしているのかを説明することです。

  • ラベルに loc を使用
  • 位置に iloc を使用する
  • 両方に ix を使用します (本当に必要な場合)

Python の禅を思い出してください:

明示的は暗黙的よりも優れています

于 2012-11-15T00:30:57.783 に答える
10

pandas 0.14.0 以降では、スライスオブジェクトを含むタプルを提供することで、マルチインデックス オブジェクトをスライスできます。.loc

In [2]: s.loc[('b', slice(2, 10))]
Out[2]:
b  2   -1.206052
   4   -0.735682
dtype: float64
于 2015-07-18T11:53:55.230 に答える
4

私が考えることができる最善の方法は、この場合「選択」を使用することです。ドキュメントには、「この方法は、これ以上直接的な方法がない場合にのみ使用する必要があります」とさえ書かれていますが。

データの索引付けと選択

In [116]: s
Out[116]: 
a  0     1.724372
   1     0.305923
   5     1.780811
b  0    -0.556650
   1     0.207783
   4    -0.177901
   50    0.289365
   0     1.168115

In [117]: s.select(lambda x: x[0] == 'b' and 2 <= x[1] <= 10)
Out[117]: b  4   -0.177901
于 2012-11-15T00:47:54.870 に答える
0

これが理想的かどうかはわかりませんが、マスクを作成することで機能します

In [59]: s.index
Out[59]: 
MultiIndex
[('a', 0) ('a', 1) ('a', 5) ('b', 0) ('b', 1) ('b', 2) ('b', 4)
 ('b', 50) ('c', 0)]
In [77]: s[(tpl for tpl in s.index if 2<=tpl[1]<=10 and tpl[0]=='b')]                                                               
Out[77]: 
b  2   -0.586568
   4    1.559988

編集:ヘイデンの解決策が道です

于 2012-11-15T00:16:53.580 に答える