팬더 : 다단계 열 색인에서 수준을 삭제 하시겠습니까?


242

다단계 열 인덱스가있는 경우 :

>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> pd.DataFrame([[1,2], [3,4]], columns=cols)
    ㅏ
   --- +-
    b | 씨
-+ --- +-
0 | 1 | 2
1 | 3 | 4

해당 인덱스의 "a"수준을 어떻게 떨어 뜨릴 수 있습니까?

    b | 씨
-+ --- +-
0 | 1 | 2
1 | 3 | 4

3
인덱스와 열 모두에 대해 DataFrame 메서드를 사용하는 것이 좋습니다. 인덱스 수준을 삭제하거나 선택합니다.
Sören

@ Sören stackoverflow.com/a/56080234/3198568을 확인하십시오 . droplevel작품은 매개 변수를 통해 여러 수준의 인덱스 또는 열에서 작동 할 수 있습니다 axis.
아이린

답변:


306

당신은 사용할 수 있습니다 MultiIndex.droplevel:

>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> df = pd.DataFrame([[1,2], [3,4]], columns=cols)
>>> df
   a   
   b  c
0  1  2
1  3  4

[2 rows x 2 columns]
>>> df.columns = df.columns.droplevel()
>>> df
   b  c
0  1  2
1  3  4

[2 rows x 2 columns]

55
어떤 레벨이 떨어졌는지 명시 적으로 말하는 것이 가장 좋습니다. 레벨은 위에서부터 0으로 색인됩니다. >>> df.columns = df.columns.droplevel(0)
Ted Petrou

6
삭제하려는 색인이 맨 위 (열)가 아닌 왼쪽 (행)에있는 경우 "열"을 "색인"으로 변경하고 동일한 방법을 사용할 수 있습니다.>>> df.index = df.index.droplevel(1)
Idodo

7
Panda 버전 0.23.4에서는 df.columns.droplevel()더 이상 사용할 수 없습니다.
yoonghm

8
@yoonghm 그것은 당신은 아마 다중 색인하지 않아도 열이 그것을 요구하고,이
매트 해리슨

1
나는 세 가지 수준을 가지고 있었고 중간 수준으로 떨어 뜨리고 싶었습니다. 가장 낮은 수준 (수준 [2])과 가장 높은 수준 (수준 [0])을 떨어 뜨리는 것이 가장 효과적이라는 것을 알았습니다. >>>df.columns = df.columns.droplevel(2) >>>df.columns = df.columns.droplevel(0)
Kyle C

65

인덱스를 삭제하는 또 다른 방법은 목록 이해를 사용하는 것입니다.

df.columns = [col[1] for col in df.columns]

   b  c
0  1  2
1  3  4

이 전략은 아래 레벨과 같이 두 레벨의 이름을 결합하려는 경우에도 유용합니다. 맨 아래 레벨에는 두 개의 'y'가 있습니다.

cols = pd.MultiIndex.from_tuples([("A", "x"), ("A", "y"), ("B", "y")])
df = pd.DataFrame([[1,2, 8 ], [3,4, 9]], columns=cols)

   A     B
   x  y  y
0  1  2  8
1  3  4  9

최상위 수준을 삭제하면 인덱스 'y'가있는 두 개의 열이 남습니다. 목록 이해와 이름을 결합하여 피할 수 있습니다.

df.columns = ['_'.join(col) for col in df.columns]

    A_x A_y B_y
0   1   2   8
1   3   4   9

그것은 그룹화를 한 후에 내가 겪었던 문제이며 그것을 해결 한 다른 질문 을 찾는 데 시간 걸렸 습니다. 이 솔루션을 특정 사례에 맞게 조정했습니다.


2
[col[1] for col in df.columns]더 직접적 df.columns.get_level_values(1)입니다.
Eric O Lebigot

2
일부 열에 빈 레벨 값이있는 비슷한 요구가있었습니다. 다음을 사용합니다.[col[0] if col[1] == '' else col[1] for col in df.columns]
Logan

43

이 작업을 수행하는 또 다른 방법 은 .xs 방법을 사용하여의 df단면을 기반으로 다시 할당 하는 것입니다.df

>>> df

    a
    b   c
0   1   2
1   3   4

>>> df = df.xs('a', axis=1, drop_level=True)

    # 'a' : key on which to get cross section
    # axis=1 : get cross section of column
    # drop_level=True : returns cross section without the multilevel index

>>> df

    b   c
0   1   2
1   3   4

1
전체 열 수준에 대해 단일 레이블이있을 때만 작동합니다.
Ted Petrou

1
두 번째 수준을 삭제하려는 경우 작동하지 않습니다.
Sören

동일한 수준으로 슬라이스 앤 드롭하려는 경우이 방법이 좋습니다. 두 번째 수준에서 슬라이스 (예 b:)하고 해당 수준을 삭제하고 첫 번째 수준 ( a) 으로 남겨 두 려면 다음과 같이 작동합니다.df = df.xs('b', axis=1, level=1, drop_level=True)
Tiffany G. Wilson

27

Pandas 0.24.0부터는 이제 DataFrame.droplevel ()을 사용할 수 있습니다 .

cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
df = pd.DataFrame([[1,2], [3,4]], columns=cols)

df.droplevel(0, axis=1) 

#   b  c
#0  1  2
#1  3  4

이것은 DataFrame 메서드 체인 롤링을 유지하려는 경우에 매우 유용합니다.


이것은 "제자리에서"수정하지 않고 새 DataFrame을 반환한다는 점에서 "가장 순수한"솔루션입니다.
EliadL

16

열의 이름을 변경하여이를 달성 할 수도 있습니다.

df.columns = ['a', 'b']

여기에는 수동 단계가 포함되지만 특히 데이터 프레임의 이름을 바꾸려는 경우 옵션이 될 수 있습니다.


이것이 본질적으로 민트의 첫 번째 답변이하는 것입니다. 이제는에서 제공 한 이름 목록 (일반적으로 지루한 이름)을 지정할 필요가 없습니다 df.columns.get_level_values(1).
Eric O Lebigot

13

sum level = 1과 함께 사용하는 작은 트릭 (level = 1이 모두 고유 한 경우 작동)

df.sum(level=1,axis=1)
Out[202]: 
   b  c
0  1  2
1  3  4

더 일반적인 솔루션 get_level_values

df.columns=df.columns.get_level_values(1)
df
Out[206]: 
   b  c
0  1  2
1  3  4

4

droplevel () 함수가 작동하지 않는 이유를 모르기 때문에이 문제로 어려움을 겪었습니다. 여러 작업을 수행하고 테이블의 'a'는 열 이름이고 'b', 'c'는 색인이라는 것을 배우십시오. 이렇게하면 도움이 될 것입니다

df.columns.name = None
df.reset_index() #make index become label

1
원하는 출력이 전혀 재생되지 않습니다.
Eric O Lebigot

게시 날짜를 기준으로, 드롭 레벨이 Pandas 버전에 포함되지 않았을 수 있습니다 (2019 년 1 월 24.0 안정 버전에 추가됨)
LinkBerest
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.