Pandas MultiIndex DataFrame에서 행 선택


146

인덱스가 MultiIndex 인 데이터 프레임의 행을 선택 / 필터링하는 가장 일반적인 Pandas 방법은 무엇입니까?

  • 단일 값 / 라벨을 기준으로 슬라이스
  • 하나 이상의 수준에서 여러 레이블을 기반으로 슬라이스
  • 부울 조건 및 표현식 필터링
  • 어떤 상황에서 적용 가능한 방법

단순성을위한 가정 :

  1. 입력 데이터 프레임에 중복 인덱스 키가 없습니다.
  2. 아래의 입력 데이터 프레임에는 두 가지 수준 만 있습니다. (여기에 표시된 대부분의 솔루션은 N 레벨로 일반화됩니다.)

입력 예 :

mux = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    list('tuvwtuvwtuvwtuvw')
], names=['one', 'two'])

df = pd.DataFrame({'col': np.arange(len(mux))}, mux)

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    u      5
    v      6
    w      7
    t      8
c   u      9
    v     10
d   w     11
    t     12
    u     13
    v     14
    w     15

질문 1 : 단일 항목 선택

"1"수준에서 "a"가있는 행을 어떻게 선택합니까?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

또한 출력에서 ​​레벨 "1"을 어떻게 드롭 할 수 있습니까?

     col
two     
t      0
u      1
v      2
w      3

질문 1b
레벨 "2"에서 값 "t"를 가진 모든 행을 어떻게 슬라이스합니까?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

질문 2 : 레벨에서 여러 값 선택

레벨 "1"에서 항목 "b"및 "d"에 해당하는 행을 어떻게 선택할 수 있습니까?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

질문 2b
"2"수준에서 "t"및 "w"에 해당하는 모든 값을 얻으려면 어떻게해야합니까?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

질문 3 : 단일 횡단면 슬라이스 (x, y)

인덱스에 대한 특정 값이있는 단일 행과 같은 횡단면을 어떻게 검색 df합니까? 특히, 어떻게의 단면을 검색 할 ('c', 'u')의해 주어진,

         col
one two     
c   u      9

질문 4 : 여러 횡단면 분할 [(a, b), (c, d), ...]

('c', 'u')및에 해당하는 두 행을 어떻게 선택 ('a', 'w')합니까?

         col
one two     
c   u      9
a   w      3

질문 5 : 레벨 당 슬라이스 된 항목 1 개

"1"수준의 "a"또는 "2"수준의 "t"에 해당하는 모든 행을 검색하려면 어떻게해야합니까?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

질문 6 : 임의 슬라이스

특정 단면을 슬라이스하려면 어떻게해야합니까? "a"와 "b"의 경우 하위 수준이 "u"및 "v"인 모든 행을 선택하고 "d"의 경우 하위 수준이 "w"인 행을 선택하고 싶습니다.

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

질문 7은 숫자 수준으로 구성된 고유 한 설정을 사용합니다.

np.random.seed(0)
mux2 = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    np.random.choice(10, size=16)
], names=['one', 'two'])

df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2)

         col
one two     
a   5      0
    0      1
    3      2
    3      3
b   7      4
    9      5
    3      6
    5      7
    2      8
c   4      9
    7     10
d   6     11
    8     12
    8     13
    1     14
    6     15

질문 7 : 다중 인덱스의 개별 수준에서 숫자 부등식으로 필터링

"2"수준의 값이 5보다 큰 모든 행을 가져 오려면 어떻게합니까?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

참고 :이 게시물은 MultiIndex를 만드는 방법, 할당 작업을 수행하는 방법 또는 성능 관련 토론을 다루지 않습니다 (이 내용은 나중에 별도의 주제 임).

답변:


166

멀티 인덱싱 / 고급 인덱싱

참고이
게시물은 다음과 같은 방식으로 구성됩니다.

  1. OP에 제시된 질문은 하나씩 처리됩니다.
  2. 각 질문에 대해이 문제를 해결하고 예상 된 결과를 얻는 데 적용 할 수있는 하나 이상의 방법이 시연됩니다.

추가 기능, 구현 세부 정보 및 당면한 주제에 대한 간단한 정보에 관심이있는 독자를 위해 참고 (이와 매우 유사 함)가 포함됩니다. 이 노트는 문서를 샅샅이 뒤지고 다양한 모호한 기능을 발견하고 내 자신의 (제한된) 경험을 통해 수집되었습니다.

모든 코드 샘플은 pandas v0.23.4, python3.7 에서 생성 및 테스트되었습니다 . 명확하지 않거나 사실적으로 잘못된 것이 있거나 사용 사례에 적용 할 수있는 해결책을 찾지 못한 경우 자유롭게 편집을 제안하거나 의견에 대한 설명을 요청하거나 새 질문을여십시오. 해당되는 경우 .... .

다음은 우리가 자주 다시 살펴볼 몇 가지 일반적인 관용구 (이하 Four Idioms라고 함)에 대한 소개입니다.

  1. DataFrame.loc-라벨 별 선택을위한 일반적인 솔루션 ( pd.IndexSlice슬라이스와 관련된 더 복잡한 애플리케이션의 경우 + )

  2. DataFrame.xs -Series / DataFrame에서 특정 단면을 추출합니다.

  3. DataFrame.query-슬라이싱 및 / 또는 필터링 작업을 동적으로 지정합니다 (즉, 동적으로 평가되는 표현식으로. 다른 시나리오보다 일부 시나리오에 더 적용 가능합니다. 또한 다중 인덱스에 대한 쿼리에 대한 문서의이 섹션을 참조하십시오 .

  4. 를 사용하여 생성 된 마스크를 사용한 부울 인덱싱 MultiIndex.get_level_values( Index.isin특히 여러 값으로 필터링 할 때 와 함께 자주 사용 ). 이것은 또한 일부 상황에서 매우 유용합니다.

주어진 상황에 적용 할 수있는 내용을 더 잘 이해하기 위해 4 가지 관용구 측면에서 다양한 슬라이싱 및 필터링 문제를 살펴 보는 것이 좋습니다. 모든 관용구가 모든 상황에서 똑같이 잘 작동하지는 않는다는 것을 이해하는 것이 매우 중요합니다. 관용구가 아래 문제에 대한 잠재적 해결책으로 나열되지 않은 경우 해당 관용구를 해당 문제에 효과적으로 적용 할 수 없습니다.


질문 1

"1"수준에서 "a"가있는 행을 어떻게 선택합니까?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

loc대부분의 상황에 적용 할 수있는 범용 솔루션으로을 사용할 수 있습니다 .

df.loc[['a']]

이 시점에서

TypeError: Expected tuple, got str

이는 이전 버전의 pandas를 사용하고 있음을 의미합니다. 업그레이드를 고려하십시오! 그렇지 않으면 df.loc[('a', slice(None)), :].

또는 xs단일 단면을 추출하므로 여기에서 사용할 수 있습니다 . levelsaxis인수에 유의하십시오 (여기에서 합리적인 기본값을 가정 할 수 있음).

df.xs('a', level=0, axis=0, drop_level=False)
# df.xs('a', drop_level=False)

여기서는 결과 (우리가 슬라이스 한 수준)에서 "1"수준이 떨어지는 drop_level=False것을 방지하기 위해 인수가 필요합니다 xs.

여기에 또 다른 옵션은 다음을 사용하는 것입니다 query.

df.query("one == 'a'")

인덱스에 이름이없는 경우 쿼리 문자열을 "ilevel_0 == 'a'".

마지막으로 다음을 사용합니다 get_level_values.

df[df.index.get_level_values('one') == 'a']
# If your levels are unnamed, or if you need to select by position (not label),
# df[df.index.get_level_values(0) == 'a']

또한 출력에서 ​​레벨 "1"을 어떻게 드롭 할 수 있습니까?

     col
two     
t      0
u      1
v      2
w      3

이것은 다음 중 하나를 사용하여 쉽게 수행 할 수 있습니다.

df.loc['a'] # Notice the single string argument instead the list.

또는,

df.xs('a', level=0, axis=0, drop_level=True)
# df.xs('a')

drop_level인수를 생략 할 수 있습니다 ( True기본적으로 가정 됨 ).

참고
필터링 된 DataFrame은 DataFrame을 인쇄 할 때 표시되지 않더라도 여전히 모든 수준을 가질 수 있습니다. 예를 들면

v = df.loc[['a']]
print(v)
         col
one two     
a   t      0
    u      1
    v      2
    w      3

print(v.index)
MultiIndex(levels=[['a', 'b', 'c', 'd'], ['t', 'u', 'v', 'w']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
           names=['one', 'two'])

다음을 사용하여 이러한 수준을 제거 할 수 있습니다 MultiIndex.remove_unused_levels.

v.index = v.index.remove_unused_levels()

print(v.index)
MultiIndex(levels=[['a'], ['t', 'u', 'v', 'w']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3]],
           names=['one', 'two'])

질문 1b

레벨 "2"에서 값 "t"를 가진 모든 행을 어떻게 슬라이스합니까?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

직관적으로 다음과 slice()같은 것을 원할 것입니다 .

df.loc[(slice(None), 't'), :]

It Just Works! ™하지만 투박합니다. pd.IndexSlice여기서 API를 사용하여보다 자연스러운 슬라이싱 구문을 촉진 할 수 있습니다.

idx = pd.IndexSlice
df.loc[idx[:, 't'], :]

이것은 훨씬 더 깨끗합니다.

참고 열에
후행 슬라이스가 :필요한 이유는 무엇 입니까? 는 loc두 축 ( axis=0또는 axis=1)을 따라 선택하고 슬라이스하는 데 사용할 수 있기 때문 입니다. 슬라이싱을 수행 할 축을 명시 적으로 지정하지 않으면 작업이 모호해집니다. 슬라이싱 에 대한 문서 에서 큰 빨간색 상자를 참조하십시오 .

모호한 음영을 제거 loc하려면 axis 매개 변수를 허용합니다 .

df.loc(axis=0)[pd.IndexSlice[:, 't']]

axis매개 변수가 없으면 (즉,을 수행하여 df.loc[pd.IndexSlice[:, 't']]) slicing이 열에있는 것으로 가정 KeyError하고이 상황에서 a 가 발생합니다.

이것은 슬라이서에 설명되어 있습니다. 그러나이 게시물의 목적을 위해 모든 축을 명시 적으로 지정합니다.

으로 xs, 그것은이다

df.xs('t', axis=0, level=1, drop_level=False)

으로 query, 그것은이다

df.query("two == 't'")
# Or, if the first level has no name, 
# df.query("ilevel_1 == 't'") 

마지막으로을 사용 get_level_values하면

df[df.index.get_level_values('two') == 't']
# Or, to perform selection by position/integer,
# df[df.index.get_level_values(1) == 't']

모두 같은 효과입니다.


질문 2

레벨 "1"에서 항목 "b"및 "d"에 해당하는 행을 어떻게 선택할 수 있습니까?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

loc을 사용하면 목록을 지정하여 유사한 방식으로 수행됩니다.

df.loc[['b', 'd']]

위의 "b"및 "d"선택 문제를 해결하려면 다음을 사용할 수도 있습니다 query.

items = ['b', 'd']
df.query("one in @items")
# df.query("one == @items", parser='pandas')
# df.query("one in ['b', 'd']")
# df.query("one == ['b', 'd']", parser='pandas')

참고
예, 기본 파서는 'pandas'이지만이 구문이 일반적으로 파이썬이 아니라는 점을 강조하는 것이 중요합니다. Pandas 파서는 표현식과 약간 다른 구문 분석 트리를 생성합니다. 이는 일부 작업을보다 직관적으로 지정하기 위해 수행됩니다. 자세한 내용은 pd.eval ()을 사용하여 pandas의 Dynamic Expression Evaluation에 대한 내 게시물을 참조하십시오 .

그리고 get_level_values+ Index.isin:

df[df.index.get_level_values("one").isin(['b', 'd'])]

질문 2b

레벨 "2"에서 "t"및 "w"에 해당하는 모든 값을 어떻게 얻을 수 있습니까?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

loc이 가능 단지 와 연동 해에 pd.IndexSlice.

df.loc[pd.IndexSlice[:, ['t', 'w']], :] 

제 대장 :pd.IndexSlice[:, ['t', 'w']]수단은, 상기 제 레벨을 가로 질러 슬라이스. 쿼리되는 수준의 깊이가 증가함에 따라 더 많은 슬라이스를 지정해야합니다. 그러나 슬라이스되는 레벨 이상으로 더 많은 레벨을 지정할 필요는 없습니다 .

으로는 query,이입니다

items = ['t', 'w']
df.query("two in @items")
# df.query("two == @items", parser='pandas') 
# df.query("two in ['t', 'w']")
# df.query("two == ['t', 'w']", parser='pandas')

부착 get_level_values하고 Index.isin(상기와 유사 함) :

df[df.index.get_level_values('two').isin(['t', 'w'])]

질문 3

인덱스에 대한 특정 값이있는 단일 행과 같은 횡단면을 어떻게 검색 df합니까? 특히, 어떻게의 단면을 검색 할 ('c', 'u')의해 주어진,

         col
one two     
c   u      9

loc키 튜플을 지정하여 사용 합니다.

df.loc[('c', 'u'), :]

또는,

df.loc[pd.IndexSlice[('c', 'u')]]

참고이
시점에서 PerformanceWarning다음과 같은 문제가 발생할 수 있습니다 .

PerformanceWarning: indexing past lexsort depth may impact performance.

이는 색인이 정렬되지 않았 음을 의미합니다. pandas는 최적의 검색 및 검색을 위해 정렬되는 인덱스 (이 경우 문자열 값을 다루기 때문에 사전 순)에 의존합니다. 빠른 수정은 DataFrame.sort_index. 이러한 쿼리를 여러 번 동시에 수행하려는 경우 성능 관점에서 특히 바람직합니다.

df_sort = df.sort_index()
df_sort.loc[('c', 'u')]

MultiIndex.is_lexsorted()색인이 정렬되었는지 여부를 확인 하는 데 사용할 수도 있습니다 . 이 함수는 True또는 False그에 따라 반환합니다 . 이 함수를 호출하여 추가 정렬 단계가 필요한지 여부를 결정할 수 있습니다.

를 사용하면 xs다른 모든 인수를 적절한 기본값으로 설정하여 단일 튜플을 첫 번째 인수로 다시 전달합니다.

df.xs(('c', 'u'))

를 사용 query하면 상황이 약간 어색해집니다.

df.query("one == 'c' and two == 'u'")

이제 이것은 일반화하기가 상대적으로 어려울 것임을 알 수 있습니다. 그러나이 특정 문제는 여전히 괜찮습니다.

여러 수준에 걸친 액세스로 get_level_values계속 사용할 수 있지만 권장되지는 않습니다.

m1 = (df.index.get_level_values('one') == 'c')
m2 = (df.index.get_level_values('two') == 'u')
df[m1 & m2]

질문 4

('c', 'u')및에 해당하는 두 행을 어떻게 선택 ('a', 'w')합니까?

         col
one two     
c   u      9
a   w      3

을 사용하면 다음과 loc같이 간단합니다.

df.loc[[('c', 'u'), ('a', 'w')]]
# df.loc[pd.IndexSlice[[('c', 'u'), ('a', 'w')]]]

를 사용하면 query횡단면과 레벨을 반복하여 쿼리 문자열을 동적으로 생성해야합니다.

cses = [('c', 'u'), ('a', 'w')]
levels = ['one', 'two']
# This is a useful check to make in advance.
assert all(len(levels) == len(cs) for cs in cses) 

query = '(' + ') or ('.join([
    ' and '.join([f"({l} == {repr(c)})" for l, c in zip(levels, cs)]) 
    for cs in cses
]) + ')'

print(query)
# ((one == 'c') and (two == 'u')) or ((one == 'a') and (two == 'w'))

df.query(query)

100 % 권장하지 않습니다! 그러나 가능합니다.


질문 5

"1"수준의 "a"또는 "2"수준의 "t"에 해당하는 모든 행을 검색하려면 어떻게해야합니까?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

이 사실에 할 매우 어려운 loc정확성을 보장 하고 여전히 코드 선명도를 유지. df.loc[pd.IndexSlice['a', 't']]잘못된 경우 df.loc[pd.IndexSlice[('a', 't')]](예 : 단면 선택) 로 해석됩니다 . pd.concat각 레이블을 개별적으로 처리 하는 솔루션을 생각할 수 있습니다 .

pd.concat([
    df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])

         col
one two     
a   t      0
    u      1
    v      2
    w      3
    t      0   # Does this look right to you? No, it isn't!
b   t      4
    t      8
d   t     12

그러나 행 중 하나가 중복되었음을 알 수 있습니다. 이는 해당 행이 두 슬라이싱 조건을 모두 충족하여 두 번 표시 되었기 때문입니다. 대신해야합니다.

v = pd.concat([
        df.loc[['a'],:], df.loc[pd.IndexSlice[:, 't'],:]
])
v[~v.index.duplicated()]

그러나 DataFrame에 기본적으로 원하는 중복 인덱스가 포함되어 있으면 유지되지 않습니다. 극도로주의해서 사용하십시오 .

을 사용 query하면 이것은 어리석게도 간단합니다.

df.query("one == 'a' or two == 't'")

을 사용하면 get_level_values여전히 간단하지만 우아하지는 않습니다.

m1 = (df.index.get_level_values('one') == 'a')
m2 = (df.index.get_level_values('two') == 't')
df[m1 | m2] 

질문 6

특정 단면을 슬라이스하려면 어떻게해야합니까? "a"와 "b"의 경우 하위 수준이 "u"및 "v"인 모든 행을 선택하고 "d"의 경우 하위 수준이 "w"인 행을 선택하고 싶습니다.

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

이것은 4 개 숙어의 적용 가능성을 이해하는 데 도움이되도록 추가 한 특별한 경우입니다. 이것은 슬라이스가 매우 구체적이고 실제 패턴을 따르지 않기 때문에 어느 것도 효과적으로 작동 하지 않는 경우입니다.

일반적으로 이와 같은 슬라이싱 문제는 키 목록을에 명시 적으로 전달해야합니다 loc. 이를 수행하는 한 가지 방법은 다음과 같습니다.

keys = [('a', 'u'), ('a', 'v'), ('b', 'u'), ('b', 'v'), ('d', 'w')]
df.loc[keys, :]

타이핑을 저장하려면 "a", "b"및 하위 수준을 분할하는 패턴이 있음을 인식 할 수 있으므로 분할 작업을 두 부분으로 나눌 수 concat있으며 결과는 다음 과 같습니다.

pd.concat([
     df.loc[(('a', 'b'), ('u', 'v')), :], 
     df.loc[('d', 'w'), :]
   ], axis=0)

"a"및 "b"에 대한 슬라이싱 사양 (('a', 'b'), ('u', 'v'))은 색인화되는 동일한 하위 수준이 각 수준에 대해 동일하기 때문에 약간 더 깔끔 합니다.


질문 7

"2"수준의 값이 5보다 큰 모든 행을 가져 오려면 어떻게합니까?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

이것은 query,

df2.query("two > 5")

그리고 get_level_values.

df2[df2.index.get_level_values('two') > 5]

참고이
예제와 유사하게 이러한 구문을 사용하여 임의의 조건을 기준으로 필터링 할 수 있습니다. 일반적으로, 그 기억 유용 loc하고 xs있는 동안, 레이블 기반 인덱싱을 위해 특별히입니다 queryget_level_values필터링을위한 일반적인 조건 마스크를 구축하기위한 도움이됩니다.


보너스 질문

MultiIndex 을 슬라이스해야하는 경우 어떻게 합니까?

실제로 여기에있는 대부분의 솔루션은 약간만 변경하여 열에도 적용 할 수 있습니다. 치다:

np.random.seed(0)
mux3 = pd.MultiIndex.from_product([
        list('ABCD'), list('efgh')
], names=['one','two'])

df3 = pd.DataFrame(np.random.choice(10, (3, len(mux))), columns=mux3)
print(df3)

one  A           B           C           D         
two  e  f  g  h  e  f  g  h  e  f  g  h  e  f  g  h
0    5  0  3  3  7  9  3  5  2  4  7  6  8  8  1  6
1    7  7  8  1  5  9  8  9  4  3  0  3  5  0  2  3
2    8  1  3  3  3  7  0  1  9  9  0  4  7  3  2  7

다음은 열과 함께 작동하도록하기 위해 Four Idioms를 변경해야합니다.

  1. 와 슬라이스 loc, 사용

    df3.loc[:, ....] # Notice how we slice across the index with `:`. 

    또는,

    df3.loc[:, pd.IndexSlice[...]]
  2. xs적절하게 사용하려면 인수를 전달하십시오 axis=1.

  3. 를 사용하여 열 수준 값에 직접 액세스 할 수 있습니다 df.columns.get_level_values. 그런 다음 다음과 같은 작업을 수행해야합니다.

    df.loc[:, {condition}] 

    어디에 {condition}사용하여 구축 몇 가지 조건을 나타냅니다 columns.get_level_values.

  4. 를 사용하려면 query유일한 옵션은 전치, 인덱스 쿼리, 다시 전치하는 것입니다.

    df3.T.query(...).T

    권장하지 않음, 다른 세 가지 옵션 중 하나를 사용하십시오.


6

최근에 위의 솔루션 중 어느 것도 원하는 결과를 생성 할 수없는 3+ 수준의 다중 인덱스 데이터 프레임이있는 사용 사례를 발견했습니다. 물론 위의 솔루션이 내 사용 사례에서 작동 할 가능성이 높으며 여러 가지를 시도했지만 사용 가능한 시간에 작동하도록 만들 수 없었습니다.

나는 전문가와는 거리가 멀지 만 위의 포괄적 인 답변에 나열되지 않은 솔루션을 우연히 발견했습니다. 나는 솔루션이 어떤 식 으로든 최적이라는 보장을하지 않습니다.

이것은 위의 질문 # 6과 약간 다른 결과를 얻는 다른 방법입니다. (및 기타 질문도 가능)

특히 나는 찾고 있었다 :

  1. 한 수준의 인덱스에서 두 개 이상의 값을 선택하고 다른 수준의 인덱스에서 단일 값을 선택하는 방법
  2. 데이터 프레임 출력에서 ​​이전 작업의 인덱스 값을 유지하는 방법입니다.

기어의 멍키 렌치로 (하지만 완전히 고정 가능) :

  1. 인덱스의 이름이 지정되지 않았습니다.

아래 장난감 데이터 프레임에서 :

    index = pd.MultiIndex.from_product([['a','b'],
                               ['stock1','stock2','stock3'],
                               ['price','volume','velocity']])

    df = pd.DataFrame([1,2,3,4,5,6,7,8,9,
                      10,11,12,13,14,15,16,17,18], 
                       index)

                        0
    a stock1 price      1
             volume     2
             velocity   3
      stock2 price      4
             volume     5
             velocity   6
      stock3 price      7
             volume     8
             velocity   9
    b stock1 price     10
             volume    11
             velocity  12
      stock2 price     13
             volume    14
             velocity  15
      stock3 price     16
             volume    17
             velocity  18

물론 아래 작품을 사용하면 :

    df.xs(('stock1', 'velocity'), level=(1,2))

        0
    a   3
    b  12

하지만 다른 결과를 원했기 때문에 그 결과를 얻는 방법은 다음과 같습니다.

   df.iloc[df.index.isin(['stock1'], level=1) & 
           df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
    b stock1 velocity  12

그리고 한 수준에서 두 개 이상의 값을, 다른 수준에서 단일 (또는 2+) 값을 원하는 경우 :

    df.iloc[df.index.isin(['stock1','stock3'], level=1) & 
            df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
      stock3 velocity   9
    b stock1 velocity  12
      stock3 velocity  18

위의 방법은 아마도 약간 투박하지만 내 요구를 충족 시켰고 보너스로 이해하고 읽기가 더 쉬웠습니다.


2
좋아,에 대한 level논쟁에 대해 몰랐다 Index.isin.
cs95
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.