Py) Pandas - Styling-01

Py) Pandas - Styling-01

Python의 Pandas는 Jupyter Notebook에서 출력되는 DataFrame을 꾸밀 수 있도록 styling 이라는 기능을 제공하고 있다. 기초부터 시작해보자.


Pandas Styling은 Jupyter Notebook에서 출력되는 출력물이 웹브라우저를 기반으로 하기 때문에 HTML태그, CSS 등을 사용한 별도의 꾸미기 기능을 제공하는 것이다. Python의 기본 객체와 Pandas의 Series에는 해당이 되지 않는 내용이며 DataFrame 객체에만 이를 쓸 수 있다.

원리

Jupyter Notebook을 사용하는 것은 곧 웹 브라우저 기반으로 출력물을 확인하는 것을 뜻한다. 그래서 사용자가 원하는 위치에 별도의 코드를 추가하여 DataFrame을 좀 더 꾸밀 수 있으며 주로 각 요소의 스타일을 담당하는 CSS 코드를 추가하는 것이다.
좀 더 자세하게 알아보면 각 셀에 해당하는 ID 기반의 CSS코드가 추가되는 것임을 알 수 있다. ID기반의 CSS코드를 생성하기 때문에 inline CSS를 직접 추가하는 효과와 다를바 없다고 할 수 있겠다.

데이터 준비

먼저 다음과 같은 데이터를 준비하도록 한다.

1
2
3
4
5
6
7
import pandas as pd
import numpy as np

np.random.seed(123)
df = pd.DataFrame(np.random.randn(3, 4),
columns = ["A", "B", "C", "D"])
df
A B C D
0 -1.085631 0.997345 0.282978 -1.506295
1 -0.578600 1.651437 -2.426679 -0.428913
2 1.265936 -0.866740 -0.678886 -0.094709

스타일 적용

NumPy와 Pandas를 사용하여 생성한 평범한 DataFrame 객체이다.
이제 간단한 사용자 정의 함수 color_np() 를 생성해보자.

1
2
3
4
5
6
7
def color_np(value):
if value < 0:
color = "red"
else:
color = "blue"

return "color: " + color

color_np() 는 입력값이 음수면 빨강, 그렇지 않으면 파랑을 “color” 객체에 저장하며 마지막으로 문자열을 이어붙인 결과물을 출력하게 된다. 실행 예시는 다음과 같다.

1
2
color_np(-21)
## 'color: red'

이 함수를 DataFrame에 적용해보자.

1
df.style.applymap(color_np)
A B C D
0 -1.085631 0.997345 0.282978 -1.506295
1 -0.578600 1.651437 -2.426679 -0.428913
2 1.265936 -0.866740 -0.678886 -0.094709

style accessor의 .applymap() 메서드는 특정 함수를 DataFrame의 모든 값에 일괄 적용하는 메서드이다. 그렇다면 적용하는 함수를 조금 바꾸어서 그 결과가 어떻게 바뀌는지 확인해보자.

1
2
3
4
5
6
7
def color_np_gb(value):
if value < 0:
color = "#00FF00"
else:
color = "#0000FF"

return "color: " + color

color_np_gb() 함수는 값이 음수이면 초록색이고 그렇지 않으면 파란색으로 지정하기 위해 만든 사용자 정의 함수이다. 해당 함수를 DataFrame에 적용한 결과는 다음과 같다.

1
df.style.applymap(color_np_gb)
A B C D
0 -1.085631 0.997345 0.282978 -1.506295
1 -0.578600 1.651437 -2.426679 -0.428913
2 1.265936 -0.866740 -0.678886 -0.094709

역시나 값에 따라 색상이 다르게 적용된 것을 볼 수 있다.
여기에서 더 나아가 내가 원할 때 임의로 색상을 바꿀 수 있게 하려면 다음과 같이 할 수 있다.

1
2
3
4
5
6
7
8
def color_np_custom(value, c1, c2):
if value < 0:
color = c1
else:
color = c2
return "color: " + color

df.style.applymap(color_np_custom, c1 = "#FF0000", c2 = "#0000BB")
A B C D
0 -1.085631 0.997345 0.282978 -1.506295
1 -0.578600 1.651437 -2.426679 -0.428913
2 1.265936 -0.866740 -0.678886 -0.094709

새로 정의한 color_np_custom() 함수를 사용할 경우 “c1”, “c2” 인자에 사용자가 색상을 지정하면 해당 색상으로 값이 지정된다.

스타일 부분 적용

앞에서 사용한 color_np() 함수를 사용하고 .applymap() 메서드 또한 그대로 사용한다. 여기서 .applymap() 메서드의 “subset” 인자에 값을 할당하여 스타일을 부분적용할 수 있으며 코드는 다음과 같다.

1
2
df.style.applymap(color_np,
subset = pd.IndexSlice[[1, 2], ["B", "D"]])
A B C D
0 -1.085631 0.997345 0.282978 -1.506295
1 -0.578600 1.651437 -2.426679 -0.428913
2 1.265936 -0.866740 -0.678886 -0.094709

마치 DataFrame의 .loc 인덱서를 사용하는 것 처럼 쉼표 앞에는 row 인덱스를 명시하고 쉼표 뒤에는 column 인덱스를 명시하면 된다. 여기서 pd.IndexSlice[] 는 함수처럼 소괄호를 사용하는 것이 아닌 다른 .loc, .iloc 와 같이 대괄호를 사용하니 주의하도록 하자.

마치며

여기서는 색상을 대상으로 코드를 작성했지만 CSS를 활용하면 색상 뿐만 아니라 문자의 정렬이나 서체 등 다양한 영역을 사용자의 입맛에 맞게 바꿀 수 있다.


<Python Pandas Styling 시리즈>
Python Pandas Styling - 01
Python Pandas Styling - 02
Python Pandas Styling - 03
Python Pandas Styling - 04

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×