본문 바로가기
Python/Pandas

멀티인덱스의 슬라이스(slice)와 단면(cross-section)추출-pandas(44)

by 콩돌 2020. 12. 27.
반응형

파이썬 버전 3.8 기준

pandas 버전 1.1.4 기준


 멀티인덱스의 슬라이스와 단면추출


본 포스팅에서는 멀티인덱스에서의 슬라이스와, 단면추출을 하는 방법에 대해 다뤄보도록 한다.

이를 위해 pandas.IndexSlice와 xs메서드를 다룬다.

 

 슬라이서의 사용

 

사용자는 MultiIndex에서 다수의 인덱서(indexer)를 사용하는 것으로 슬라이싱 할 수 있다.


슬라이싱을 할때 레이블에 의해 인덱싱이 가능하다(선택자(Selector)를 이용한 인덱싱 등). 

  ○ 선택자는 슬라이싱, 레이블의 리스트, 레이블들, 불린인덱서를 포함한다.

  ○ 상세한건 이전의 슬라이스 포스팅(슬라이싱을 이용한 선택)을 참고하자.


사용자는 특정 Level의 모든 내용물을 선택하기 위해 slice(None)을 사용할 수 있다.

  ○ sllice(None)은 암묵적 하위에 있는 Level을 표현한다.

  ○ 즉, 사용자는 더 하위에 있는 Level을 굳이 명시할 필요가 없다.


일반적으로, 레이블 인덱싱이므로 슬라이서의 양쪽 끝이 포함되는 경우가 많다.


※ 경고

인덱스와 열에 대한 인덱서를 의미하기 떄문에, 사용자는 .loc 지정자에서 모든 축을 지정하여야 한다.

입력된 인덱서가 행의 MultiIndex가 아니라 두 축의 인덱싱으로 잘못 해석 될 수 있는 모호한 경우가 있다.

따라서 사용자는 다음과 같이 활용하여야 한다.

df.loc[(slice('A1', 'A3'), ...), : ]


다음과 같이는 사용하지 말도록 한다.

df.loc[(slice('A1', 'A3'), ...) ]



 슬라이스 사용 예제

슬라이스, 리스트, 레이블 등을 사용한 기초적인 MultiIndex 슬라이싱 예제들을 다뤄보도록 한다.

예제를 수행하기에 앞서 다음과 같이 모듈의 import와 멀티인덱스를 보유하는 DataFrame을 정의한다.

 

모듈의 임폴트 및 예제용 DataFrame의 정의)

# pandas와 numpy의 import

In[2]: import pandas as pd

In[3]: import numpy as np


# row 멀티인덱스 정의

In[4]: ex_prod_row=[['A','B','C','D'], ['a','b'], ['L0','L1']]

In[5]: ex_index_row=pd.MultiIndex.from_product(ex_prod_row, names=['one','two','three'])


# Columns 멀티인덱스 정의

In[6]: ex_prod_col=[['W','X','Y','Z'], ['x','y']]

In[7]: ex_index_col=pd.MultiIndex.from_product(ex_prod_col, names=['one','two'])


# 예제용 DataFrame 정의

In[8]: ex_df_mul=pd.DataFrame([range(x*8,x*8+8) for x in range(16)], index=ex_index_row, columns=ex_index_col)

 

아래 예제는 slice()함수를 이용한 슬라이스와 레이블을 통한 데이터 선택의 예제를 보여준다.

 

slice()함수를 이용한 슬라이스 예제)

# slice() 함수를 이용한 슬라이스 예제

In[9]: ex_df_mul.loc[(slice('B','C'), slice(None)), : ]

Out[9]: 

one             W       X       Y       Z    

two             x   y   x   y   x   y   x   y

one two three                                

B   a   L0     32  33  34  35  36  37  38  39

        L1     40  41  42  43  44  45  46  47

    b   L0     48  49  50  51  52  53  54  55

        L1     56  57  58  59  60  61  62  63

C   a   L0     64  65  66  67  68  69  70  71

        L1     72  73  74  75  76  77  78  79

    b   L0     80  81  82  83  84  85  86  87

        L1     88  89  90  91  92  93  94  95


slice() 함수와 레이블을 이용한 예제

ex_df_mul.loc['D', ( slice(None) , 'y')]

Out[20]: 

one          W    X    Y    Z

two          y    y    y    y

two three                    

a   L0      97   99  101  103

    L1     105  107  109  111

b   L0     113  115  117  119

    L1     121  123  125  127


slice(None)을 사용하기 보다는 : 를 사용하여 더욱 자연스러운 문법을 사용하는 것이 가능하다.

이를 위해 pandas.IndexSlice를 사용할 수 있다.

여러 축에 대해 이 메서드를 사용하여 꽤 복잡한 선택 작업을 동시에 수행하는 것이 가능하다.


pandas.IndexSlice 사용 예제)

# pandas.IndexSlice 사용  


# pandas.IndexSlice의 정의

In[10]: Easy_index = pd.IndexSlice


# pandas.IndexSlice 사용 예제 1 

In[11]: ex_df_mul.loc[Easy_index[ ['A', 'B'], : , : ], : ]

Out[11]: 

one             W       X       Y       Z    

two             x   y   x   y   x   y   x   y

one two three                                

A   a   L0      0   1   2   3   4   5   6   7

        L1      8   9  10  11  12  13  14  15

    b   L0     16  17  18  19  20  21  22  23

        L1     24  25  26  27  28  29  30  31

B   a   L0     32  33  34  35  36  37  38  39

        L1     40  41  42  43  44  45  46  47

    b   L0     48  49  50  51  52  53  54  55

        L1     56  57  58  59  60  61  62  63



# pandas.IndexSlice 사용 예제 2

In[12]: ex_df_mul.loc[Easy_index[ 'A':'C' , 'a', : ], Easy_index[ ['X', 'Z'], : ] ]

Out[12]: 

one             X       Z    

two             x   y   x   y

one two three                

A   a   L0      2   3   6   7

        L1     10  11  14  15

B   a   L0     34  35  38  39

        L1     42  43  46  47

C   a   L0     66  67  70  71

        L1     74  75  78  79


# pandas.IndexSlice 사용 예제 3

In[13]: ex_df_mul.loc[Easy_index[ 'A':'C', : , ['L0'] ], Easy_index[ 'X':'Z' , ['y'] ] ]

Out[13]: 

one             X   Y   Z

two             y   y   y

one two three            

A   a   L0      3   5   7

    b   L0     19  21  23

B   a   L0     35  37  39

    b   L0     51  53  55

C   a   L0     67  69  71

    b   L0     83  85  87  

 

불린인덱서를 사용하여, 사용자는 Values들과 관련된 선택을 이용할 수 있다.


불린인덱서의 사용 예제)

# 예제용 불린인덱서의 정의

In[14]: bool_indexer = ex_df_mul[ ('X', 'y') ]  > 50 


# 불린 인덱서의 사용 예제

In[15]: ex_df_mul.loc[Easy_index[bool_indexer, : , : ], Easy_index[ : , : ] ] 

Out[15]: 

one              W         X         Y         Z     

two              x    y    x    y    x    y    x    y

one two three                                        

B   b   L0      48   49   50   51   52   53   54   55

        L1      56   57   58   59   60   61   62   63

C   a   L0      64   65   66   67   68   69   70   71

        L1      72   73   74   75   76   77   78   79

    b   L0      80   81   82   83   84   85   86   87

        L1      88   89   90   91   92   93   94   95

D   a   L0      96   97   98   99  100  101  102  103

        L1     104  105  106  107  108  109  110  111

    b   L0     112  113  114  115  116  117  118  119

        L1     120  121  122  123  124  125  126  127  


사용자는 하나의 축에서 입력된 슬라이서를 설명하기 위해 axis 입력변수를 .loc에 명시할 수 있다.


axis 입력변수의 사용 예제)

# axis입력변수의 사용 예제 1

In[16]: ex_df_mul.loc(axis=0)[ : , : , 'L0' ]

Out[16]: 

one              W         X         Y         Z     

two              x    y    x    y    x    y    x    y

one two three                                        

A   a   L0       0    1    2    3    4    5    6    7

    b   L0      16   17   18   19   20   21   22   23

B   a   L0      32   33   34   35   36   37   38   39

    b   L0      48   49   50   51   52   53   54   55

C   a   L0      64   65   66   67   68   69   70   71

    b   L0      80   81   82   83   84   85   86   87

D   a   L0      96   97   98   99  100  101  102  103

    b   L0     112  113  114  115  116  117  118  119

 

# axis입력변수의 사용 예제 2

In[17]: ex_df_mul.loc(axis=1)[ 'X' , 'y' ]

Out[17]: 

one  two  three

A    a    L0         3

          L1        11

     b    L0        19

          L1        27

B    a    L0        35

          L1        43

     b    L0        51

          L1        59

C    a    L0        67

          L1        75

     b    L0        83

          L1        91

D    a    L0        99

          L1       107

     b    L0       115

          L1       123

Name: (X, y), dtype: int64


멀티인덱스에서도 .loc메서드를 이용하여 배정을 사용할 수 있다.

 

.loc 메서드를 사용한 배정 예제)

# 예제를 위한 새로운 DataFrame의 정의

In[18]: import copy

In[19]: ex_df_mul2= copy.deepcopy(ex_df_mul)


# 배정 수행 예제

In[20]: ex_df_mul2.loc(axis=1)[['W','Z'],'x'] = -777

In[21]: ex_df_mul2

Out[21]: 

one              W         X         Y         Z     

two              x    y    x    y    x    y    x    y

one two three                                        

A   a   L0    -777    1    2    3    4    5 -777    7

        L1    -777    9   10   11   12   13 -777   15

    b   L0    -777   17   18   19   20   21 -777   23

        L1    -777   25   26   27   28   29 -777   31

B   a   L0    -777   33   34   35   36   37 -777   39

        L1    -777   41   42   43   44   45 -777   47

    b   L0    -777   49   50   51   52   53 -777   55

        L1    -777   57   58   59   60   61 -777   63

C   a   L0    -777   65   66   67   68   69 -777   71

        L1    -777   73   74   75   76   77 -777   79

    b   L0    -777   81   82   83   84   85 -777   87

        L1    -777   89   90   91   92   93 -777   95

D   a   L0    -777   97   98   99  100  101 -777  103

        L1    -777  105  106  107  108  109 -777  111

    b   L0    -777  113  114  115  116  117 -777  119

        L1    -777  121  122  123  124  125 -777  127

 

 

 단면의 추출

 

 Cross-section

DataFrame의 xs() 메서드는 단면을 추출할 수 있게 해주는 메서드로 데이터 선택을 더 쉽게 할 수 있게 해준다.  

이는 특정 Level에서 원하는 데이터를 더 쉽고 빠르게 출력할 수 있게 해준다.

 

xs 메서드 사용 예제)

# xc 메서드 사용 예제

In[22]: ex_df_mul.xs('L0', level='three', axis=0)

Out[22]: 

one        W         X         Y         Z     

two        x    y    x    y    x    y    x    y

one two                                        

A   a      0    1    2    3    4    5    6    7

    b     16   17   18   19   20   21   22   23

B   a     32   33   34   35   36   37   38   39

    b     48   49   50   51   52   53   54   55

C   a     64   65   66   67   68   69   70   71

    b     80   81   82   83   84   85   86   87

D   a     96   97   98   99  100  101  102  103

    b    112  113  114  115  116  117  118  119


# 위의 데이터 선택을 슬라이서를 사용하는 경우

In[23]: ex_df_mul.loc[(slice(None), slice(None), 'L0'), : ]

Out[23]: 

one              W         X         Y         Z     

two              x    y    x    y    x    y    x    y

one two three                                        

A   a   L0       0    1    2    3    4    5    6    7

    b   L0      16   17   18   19   20   21   22   23

B   a   L0      32   33   34   35   36   37   38   39

    b   L0      48   49   50   51   52   53   54   55

C   a   L0      64   65   66   67   68   69   70   71

    b   L0      80   81   82   83   84   85   86   87

D   a   L0      96   97   98   99  100  101  102  103

    b   L0     112  113  114  115  116  117  118  119


사용자는 또한 axis 입력변수를 입력하여 xs()메서드를 사용하여 열 위에서 선택할 수 있다.

  ○ axis=0이 기본값이므로 참고하자.

 

모듈의 임폴트 및 예제용 DataFrame의 정의)

# pandas와 numpy의 import

In[24]: ex_df_mul.xs('y', level='two', axis=1)

Out[24]: 

one              W    X    Y    Z

one two three                    

A   a   L0       1    3    5    7

        L1       9   11   13   15

    b   L0      17   19   21   23

        L1      25   27   29   31

B   a   L0      33   35   37   39

        L1      41   43   45   47

    b   L0      49   51   53   55

        L1      57   59   61   63

C   a   L0      65   67   69   71

        L1      73   75   77   79

    b   L0      81   83   85   87

        L1      89   91   93   95

D   a   L0      97   99  101  103

        L1     105  107  109  111

    b   L0     113  115  117  119

        L1     121  123  125  127


In[25]: ex_df_mul.loc[ : , (slice(None), 'y') ]

Out[25]: 

one              W    X    Y    Z

two              y    y    y    y

one two three                    

A   a   L0       1    3    5    7

        L1       9   11   13   15

    b   L0      17   19   21   23

        L1      25   27   29   31

B   a   L0      33   35   37   39

        L1      41   43   45   47

    b   L0      49   51   53   55

        L1      57   59   61   63

C   a   L0      65   67   69   71

        L1      73   75   77   79

    b   L0      81   83   85   87

        L1      89   91   93   95

D   a   L0      97   99  101  103

        L1     105  107  109  111

    b   L0     113  115  117  119

        L1     121  123  125  127

 

xs() 메서드를 사용하면 여러 Level에서 다수의 키(key)들을 선택할 수 있다.

 

다단계 다수의 키 선택 예제)

# 다단계 다수의 키 선택 예제 

In[26]: ex_df_mul.xs(('A', 'L1'), level=('one','three'), axis=0)

Out[26]: 

one   W       X       Y       Z    

two   x   y   x   y   x   y   x   y

two                                

a     8   9  10  11  12  13  14  15

b    24  25  26  27  28  29  30  31


# 위의 예제를 기존의 슬라이싱을 사용할 경우

In[27]: ex_df_mul.loc(axis=0)[ 'A' , : , 'L1']

Out[27]: 

one             W       X       Y       Z    

two             x   y   x   y   x   y   x   y

one two three                                

A   a   L1      8   9  10  11  12  13  14  15

    b   L1     24  25  26  27  28  29  30  31


drop_level변수를 이용하여 추출한 Level 데이터를 삭제하거나 남겨놓을 수 있다.

  ○ drop_level변수의 기본값은 True이다

 

drop_level 입력변수 사용 예제)

# drop_level에 True 값 입력 할 시(기본값)

In[28]: ex_df_mul.xs(('A', 'L1'), level=('one','three'), axis=0, drop_level=True)

Out[28]: 

one   W       X       Y       Z    

two   x   y   x   y   x   y   x   y

two                                

a     8   9  10  11  12  13  14  15

b    24  25  26  27  28  29  30  31


# drop_level에 False 값 입력 할 시

In[29]: ex_df_mul.xs(('A', 'L1'), level=('one','three'), axis=0, drop_level=False)

Out[29]: 

one             W       X       Y       Z    

two             x   y   x   y   x   y   x   y

one two three                                

A   a   L1      8   9  10  11  12  13  14  15

    b   L1     24  25  26  27  28  29  30  31

 


 DataFrame.xs(self, key, axis=0, level=None, drop_level=True)


DataFrame/Series로부터 cross-section을 반환한다.

이 메서드는 key 입력변수를 가진다. 

이 입력변수는 멀티인덱스의 특정 단계에서 데이터를 선택한다.

 

key: label, tuple of label

인덱스를 지칭하는 레이블 혹은 멀티인덱스의 일부분을 선택하는 key를 입력받는다.


axis: {0 or 'index', 1 or 'columns'}, 

기본값은 0이다.

cross-section을 검색하기 위한 축을 의미한다.


level: object

기본값으로 처음 n 단계(n=1 or len(key)) 가 입력되어 있다.

MultiIndex에 담겨있는 부분적인 하나의 키인 경우에는 어느단계가 사용되는지 나타낸다.

해당 level에 입력되는 위치를 참조하여 key에 입력되는 레이블을 찾아서 선택한다.

 

drop_level: bool

기본값으로 True가 입력되어있다.

False일 경우 같은 단계와 함께 객체를 반환한다.

 

 

 

 

 

 참고자료

  https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html

  https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.xs.html

 

 

 

 

 

 

반응형

댓글