안녕하세요~ 꽁냥이에요.
Pandas로 데이터 분석을 하다 보면 특정 위치 또는 특정 조건에 맞는 셀의 배경색을 바꿔서 알아보기 쉽게 할 필요가 있는데요. 이번 포스팅에서는 Pandas 데이터프레임에서 셀 배경색을 바꿔보는 법에 대해서 알아보겠습니다.
셀 배경색 바꾸기
이번 포스팅에서 사용할 데이터를 생성합니다.
import pandas as pd
import numpy as np
np.random.seed(24)
df = pd.DataFrame({'A': np.linspace(1, 10, 10)})
df = pd.concat([df, pd.DataFrame(np.random.randn(10, 4), columns=list('BCDE'))],
axis=1)
df.iloc[3, 3] = np.nan
df.iloc[0, 2] = np.nan
1. 특정 위치에 있는 셀 배경색 바꾸기
## 특정 위치의 배경색 바꾸기
def draw_color_cell(x,color):
color = f'background-color:{color}'
return color
df.style.applymap(draw_color_cell,color='#ff9090',subset=pd.IndexSlice[1,['B']])
line 2~4
먼저 특정 위치에 원하는 색을 칠하는 함수를 구현합니다. 여기서 적용할 데이터프레임이며 color는 셀 배경색입니다.
Pandas 데이터프레임에서 각 셀은 CSS 스타일 형식을 갖고 있어요. 그래서 배경색을 컨트롤하기 위해서는 원하는 위치의 배경색을 CSS 스타일로 지정해야 합니다. CSS에서 배경색은 'background-color : {색상}' 형식으로 지정하므로 이에 맞게 문자열을 생성해야 합니다(line 3).
line 6
스타일을 적용하기 위해서는 해당 데이터프레임에서 style.applymap 함수를 이용해야합니다. 첫번째 인자로 적용하는 함수를 넣어주어야합니다. style.applymap 함수는 해당 데이터프레임에 포함된 셀을 기본값으로 받게 되어 있습니다. draw_color_cell 함수의 x인자에 앞서 얘기한 셀이 넘어오는 것이지요. 만약 draw_color_cell 함수에 또 다른 인자가 있다면 style.applymap 함수에 따로 넣어주셔야 합니다. 이때 draw_color_cell에서 정의한 인자 이름과 동일해야 합니다. 그리고 원하는 위치는 subset인자를 통하여 지정할 수 있습니다. 그리고 style.applymap함수는 draw_color_cell 함수의 리턴값을 이용하여 셀 배경색을 바꾸어줍니다.
위 코드를 실행하면 해당 위치에 색이 칠해진 것을 알 수 있어요.
또한 subset인자를 이용하여 여러 셀의 배경색을 바꿀 수도 있습니다.
df.style.applymap(draw_color_cell,color='#ff9090',subset=pd.IndexSlice[2:5,'A':'C'])
-- 참고 --
만약 헤더 안의 셀 배경색을 바꾸고 style.set_set_table_styles을 이용해야 합니다. 열 'B'에 해당하는 셀 배경색을 바꾸고 싶다면 아래 코드와 같이 해주세요.
## 칼럼 헤더 셀 배경색 바꾸기
column = 'B' ## 원하는 칼럼이름
col_loc = df.columns.get_loc(column) ## 원하는 칼럼의 인덱스
df.style\
.set_table_styles(
[{'selector': f'th.col_heading.level0.col{col_loc}',
'props': [('background-color', '#67c5a4')]},
])
반대로 인덱스 셀을 바꾸고 싶다면 아래와 같이해주세요.
## 인덱스 셀 배경색 바꾸기
idx = 5 ## 원하는 인덱스
df.style\
.set_table_styles(
[{'selector': f'th.row_heading.level0.row{idx}',
'props': [('background-color', '#67c5a4')]},
])
2. 특정 조건에 해당하는 셀 배경색 바꾸기
1) 특정 조건을 전체 셀에 대해서 적용하는 경우
사실 특정 위치에 색을 입히는 경우보다는 특정 조건에 해당하는 부분에 색을 바꿔주는 것이 일반적입니다. 꽁냥이는 nan 값을 갖는 셀의 배경색을 바꿔보도록 할게요.
## 특정 위치의 배경색 바꾸기
def draw_color_at_nan(x,color):
if pd.isna(x):
color = f'background-color:{color}'
return color
else:
return ''
df.style.applymap(draw_color_at_nan,color='#ff9090')
line 3
해당 셀이 nan인 경우에 셀 배경색을 바꾸도록 CSS 문자열을 생성했습니다.
2) 특정 조건을 특정 열에 적용하는 경우
이번에는 'E' 열의 최대값에 해당하는 셀의 배경색을 바꾸어보겠습니다.
## 최대값에 해당하는 셀 배경색 바꾸기
def draw_color_at_maxmum(x,color):
color = f'background-color:{color}'
is_max = x == x.max()
return [color if b else '' for b in is_max]
df.style.apply(draw_color_at_maxmum,color='#ff9090',subset=['E'],axis=0)
line 2~5
여기서는 열 단위로 최대값을 구하려고 하는데요. 인자로 받은 열 데이터의 최대값이면 True, 아니면 False의 값을 갖는 리스트를 생성합니다(line 5). 그러고 나서 True인 경우 CSS 문자열을 그 외에 경우에는 빈 문자열인 리스트를 리턴해주었습니다. 앞에서는 문자열만을 리턴했지만 여기서는 리스트를 리턴하는 것에 주목해주세요.
line 7
여기서는 style.apply함수를 사용합니다. 사용 형식은 style.applymap과 거의 유사하며 차이점은 axis를 적용해주어야 해요. axis=0 이면 draw_color_at_maxmum에 (x인자에) 기본값으로 열을 넘겨주며 axis=1인 경우 행을 axis=None 이면 헤더를 제외한 데이터프레임 전체 셀을 넘겨주게 됩니다. 꽁냥이는 열 단위로 최대값을 구해야하기 때문에 axis=0으로 해두었습니다. 또한 모든 열이 아닌 'E'열의 최대값을 구하려고 하니까 axis=0으로 설정했습니다.
만약 행 단위로 최대값을 구하고 싶다면 다음과 같이 하면 됩니다.
df.style.apply(draw_color_at_maxmum,color='#ff9090',axis=1)
참고로 셀 배경색 이외에도 셀 테두리, 텍스트 크기, 텍스트 색상도 변경할 수 있습니다.
## 특정 위치의 배경색 바꾸기
def draw_color_cell(x,color,font_size,font_color,border):
color = f'background-color:{color};font-size:{font_size};color:{font_color};border:{border}'
return color
df.style.applymap(draw_color_cell,
color='#ff9090',
font_size='120%',
font_color='black',
border='2px solid yellow',
subset=pd.IndexSlice[1,['B']])
이번 포스팅에서는 데이터프레임의 셀을 꾸며보는 방법에 대해서 알아보았습니다. 궁금한 점, 잘못된 점 그리고 하고 싶은 말은 댓글로 남겨주세요.
지금까지 꽁냥이의 글 읽어주셔서 감사합니다. 안녕히 계세요~!!
'데이터 분석 > 데이터 전처리' 카테고리의 다른 글
[Pandas] 13. 날짜를 이용하여 데이터 조회하기 (0) | 2020.11.21 |
---|---|
[Pandas] 12. 행 추가/삭제하기 (0) | 2020.09.30 |
[Pandas] 10. 열/칼럼 이름 바꾸기 (0) | 2020.09.14 |
[Pandas] 9. 데이터 결합(Join)하기 (0) | 2020.09.13 |
[Pandas] 8. 랜덤으로 행 추출하기 (2) | 2020.09.12 |
댓글