ABC부트캠프 데이터 탐험가 과정

[9일차] ABC 부트캠프 파이썬을 이용한 데이터 처리 심화

hwibeenjeong 2024. 7. 16. 23:51

1. 피봇 테이블(Pivot table)

피봇 테이블이란 많은 양의 데이터에서 필요한 자료만을 뽑아 새롭게 표를 작성해주는 기능을 말한다. 그렇기 때문에 행과 열을 지정해서 원하는 데이터로 만들고, 그 안에 각각의 행렬에 맞게 데이터를 집계할 수 있다. 또한 'aggfunc' 매개변수를 통해 집계함수를 사용할 수 있다. 예시를 함께 보면 좋을 것 같다.

데이터프레임명.pivot_table(
    values = '실제 데이터가 되는 값',
    index =  '기준 레이블1',
    columns = '기준 레이블2',
    aggfunc = '집계함수'
)

비교를 원하는 값을 values의 매개변수로 넘기게 되고, index, columns의 매개변수로는 기준이 되는 레이블들을 정해준다. 이때 values를 포함해서 columns를 보면 복수형이라는 것을 알 수 있다. 이 말은 기준이 되는 레이블과 실제 데이터가 되는 값이 1개 이상이 될 수 있다는 이야기다.

 

2. 열지도(Heatmap)

열지도는 그래프의 색상을 바꿈으로써 값의 높낮이를 알 수 있다. 피봇 테이블을 만든 뒤 해당 피봇 테이블을 열지도로 바꾸게 된다면 다음과 같은 그래프를 얻을 수 있다.

그래프의 색상이 진할수록 높은 값을 의미하며, 직사각형의 형태를 띄고 있다. seaborn 라이브러리를 이용하여 열지도를 만들 수 있다. 열지도를 생성하는 함수에 색상을 지정하는 매개변수, 직사각형 안에 실질적인 데이터를 넣는 매개변수, 소수점을 지정하는 매개변수 등이 있다.

 

3. 데이터 프레임의 추가 및 삭제

우리는 지금까지 csv파일을 이용하여 데이터프레임을 만들어 왔다. 하지만, 데이터프레임도 하나의 데이터 타입인 만큼 데이터프레임을 생성하는 형태함수를 가지고 있는데, 데이터프레임을 생성하는 생성함수와 딕셔너리를 이용하여 데이터 프레임을 만들 수 있다.

df_example = pd.DataFrame({
    '1':['A', 'B', 'C', 'D'],
    '2':[1, 2, 3, 4],
})

DataFrame()함수를 통해 열이 2개이고, 행이 4개인 데이터프레임을 만들 수 있게 되었다. 이렇게 정한 값을 수정할 수도 있다.

df_example['1'] = 0

'1'이라는 열의 값을 모두 0으로 할당하는 코드이며, 대입연산자를 이용하여 데이터 프레임을 수정한다. 한 개의 열을 지정하여, 대입연산자를 이용하면 해당 열의 모든 값은 지정한 값으로 바뀌며, 만약 특정 영역에 대한 값을 바꾸기 위해서는 loc메서드를 이용한다. loc메서드를 이용하여 값을 수정하는 방법을 알아보기 전 2차원 배열에서 사용되는 대괄호를 이용하여 값을 수정하는 방법의 치명적인 오점을 확인해보자.

 

우리는 2차원 리스트의 값을 수정할 때 예를 들어 'A[1][3] = 0' 이러한 방법을 사용하여 값을 수정했었다. 하지만 데이터 프레임에서는 대괄호를 이용하여 값을 수정할 수 없게 된다. 그림을 통해 알아보기 전 우리는 값을 가져오는 방법을 확인해봐야한다. 먼저 데이터프레임에서 값을 가져오는 과정은 대부분의 변수와 비슷하게 참조가 일어난다. 예제로 리스트에서 변수를 수정하는 방법을 알아보자.

리스트에서 값을 가져오는 방법은 참조하는 형식으로 가져오게 된다. 그 말은 값을 가져올 때 getItem이라는 매직메서드가 실행된다는 뜻이다. 쉽게 말해 메모리에 저장되어 있는 값을 가져올 때 getItem이라는 방법을 써서 가져온다는 뜻이다. 만약 예제의 list[1][2]의 수정이 일어나게 되면 

다음과 같이 setItem이라는 매직메서드를 통해 수정할 수 있게 된다.

해당 개념은 조금 더 알아보고 수정할 계획이다.

데이터프레임명.loc['레이블'] = 지정하고자 하는 값

 

이러한 방식을 사용하면 지정한 레이블의 값을 지정하고자 하는 값으로 모두 대체할 수 있게 된다. 이전 시간에 loc를 이용하여 인덱싱하는 방법을 배웠다. 물론 한 개의 레이블의 모든 값을 바꿀 수 있지만 행까지 지정해준다면 특정 영역의 값들을 수정할 수 있게 된다.

데이터프레임명.loc['인덱스', '레이블'] = 지정하고자 하는 값

이렇게 인덱스와 레이블을 모두 지정해주면 특정 영역을 수정할 수 있게 된다. 만약 인덱스와 레이블 자리에 리스트가 들어간다면 1개 이상의 값들을 포함한 영역을 수정할 수 있게 된다.

 

그렇다면 데이터프레임에 값을 추가하는 방법은 어떻게 될까?

 

지금까지 loc는 기존의 레이블 혹은 인덱스를 가져오는 데에 사용되었다. 하지만 기존의 레이블 또는 인덱스 외의 다른 레이블, 인덱스를 사용하게 되면 해당 레이블과 인덱스는 새로 추가된다. 다음 예제를 살펴보자

다음과 같은 데이터프레임이 있다고 가정했을 때 'FOURTH' 레이블을 추가하는 방법을 알아보자

사진과 같이 loc로 영역을 지정해준 다음 레이블에 새로운 값을 제시해주면 새로운 열이 생성된다는 것을 알게 된다. 하지만 모든 데이터가 행렬을 따지라는 법은 없다. 기존의 데이터프레임에 새로운 값을 추가할 때 행과 열이 맞지 않게 된다면 결측값이 발생하게 된다.

 

결측값이 발생했을 때를 대비해서 데이터프레임의 삭제 방법을 알아봐야한다. 보통은 drop을 사용하게 된다. drop메서드는 지정한 값을 삭제하는 방법이다.

사진과 같이 drop메서드에 값을 지정해주고, 행방향의 값을 삭제할 것인지, 열방향의 값을 삭제할 것인지 선택할 수 있다. 사진에서는 'FOURTH'라는 열을 삭제하기 할 수 있도록 axis 매개변수의 값을 1로 설정하였다. 

또는 다음과 같이 열의 이름을 지정하여 삭제할 수 있다. 예제에서는 열을 삭제하는 방법에 대해 알아봤지만, 행에 대한 내용도 동일하다.

 

4. 데이터 프레임의 결측값 처리

이제 위에서 말한 결측값을 처리하는 방법에 대해 알아보자. 먼저 데이터 프레임에 결측값이 있는지 확인을 해봐야한다.

데이터프레임명['레이블'].isnull()

isnull 메서드를 이용하여 지정된 레이블에 결측값이 있는지 확인한다. 데이터프레임을 이루는 시리즈에 대한 메서드이며, 반환 값은 부울 대수가 포함되어 있는 시리즈를 반환하게 된다. 만약 해당 시리즈에 결측값이 발견되면 삭제하는 방법을 알아보자.

 

먼저 dropna 메서드를 이용하는 방법이다.

데이터프레임명.dropna()

위에서 봤듯이 drop은 값을 삭제하는 메서드이고, 이와 유사하게 결측값을 삭제하되, 결측값이 포함된 시리즈를 삭제하는 방법이다.  axis 매개변수를 이용하여 행을 전체 삭제할 수 있고, 열을 전체 삭제할 수 있다. 만약 결측값이 있는 레이블을 삭제하고 싶을 때는 다음의 예제와 같이 사용하면 된다.

 

info1 레이블과 info3 레이블에 결측값이 있다면 해당 행을 모두 삭제했다. 이 처럼 결측값이 포함된 데이터의 행 혹은 열을 모두 삭제하게 되면 남아있는 데이터로 분석을 진행하기에는 어려움이 있을 것이다. 그렇기 때문에 결측값을 대체하는 방법도 있다.

 

결측값을 대체하는 방법에는 fillna 메서드를 사용하는 방법이 있다. fillna 메서드는 매개변수로 어떠한 값을 넘겨주냐에 따라 각기의 기능을 수행할 수 있게 된다. 먼저 fillna를 사용하는 방법에 대해 알아보자

데이터프레임명.fillna(value = 0)
#결측값을 0으로 대체

데이터프레임명.fillna(value = {'레이블1':0, '레이블2':'na'})
# 딕셔너리에 저장된 키와 값으로 결측값을 대체

데이터프레임명.fillna(method = 'ffill')
# 결측값이 아닌 가장 첫 번째의 값으로 대체

데이터프레임명.fillna(method = 'bfill')
# 결측값이 아닌 가장 마지막 번째의 값으로 대체

만약 fillna 메서드를 진행하기 전 그룹화되어 있는 데이터프레임의 값을 변경하고자 한다면, 동일한 그룹 안에서만 적용된다는 점을 알아야한다.

 

5. 데이터 프레임의 값 변환

dtypes변수를 이용하여 데이터프레임 내부 데이터 값들의 유형을 확인할 수 있다. 하지만 astype메서드를 이용하게 된다면, 정해진 데이터 타입을 변경할 수 있다.

그림과 같이 astype 메서드를 이용해 children의 값들을 실수형으로 바꿨지만, 실제 데이터 프레임 속 데이터 값에는 변동이 없는 것을 확인할 수 있다. 이는 데이터 프레임의 값을 수정할 때 참조하여 복사를 하게 되는데 이를 저장할 변수가 없다면 변경된 값을 날라가게 된다.

 

pandas에서는 'category' 데이터 타입을 지원한다. category 데이터 타입은 특정한 유한한 수의 범주로 값을 나타내는 데 사용된다. 이는 메모리 사용량을 줄이고, 성능을 향상시키며, 데이터 표현이 명확해진다는 특징이 있다. 메모리 사용량을 줄인다는 것은 한 번에 처리할 수 있는 연산이 많아진다는 뜻이고, 이는 성능을 향상시키는 단계로 이어지게 된다.

데이터프레임명['레이블명'].astype('category')

이러한 방식으로 특정 레이블의 데이터 타입을 category로 바꿀 수 있고, 정렬 방법을 원하는 방식으로 바꿀 수 있다. 숫자형 데이터타입은 오름차순으로 정렬되고, 문자열의 경우 A-Z형식으로 정렬된다. 하지만 category 데이터 타입은 원하는 대로 정렬할 수 있다. 방법을 살펴보자.

 

데이터프레임명['레이블'].cat.reorder_categories(정렬규칙)

cat.reorder_categories 메서드는 직렬화 함수라고도 하며, category 데이터타입의 메서드들의 집합을 cat에 모아두게 된다. 그 중 reorder_categories 메서드를 불러오는 메커니즘이다. '정렬규칙'을 오름차순으로 지정해준다면 category 데이터 타입의 데이터들은 해당 정렬 규칙을 따르게 된다.  

 

6. 데이터의 구간화

데이터를 구간화하는 방법에는 두 가지가 있다. 데이터를 동일한 범위로 구간화하는 방법이 있고, 데이터의 양을 비율로 구간을 나누는 방법이 있다.

 

위의 구간화를 살펴보게 되면 내부 값에 관계 없이 데이터 전체 개수를 기준으로 동일한 비율로 구간을 나누는 방법이다. 아래의 방법은 데이터 중 정해진 값들을 기준으로 구간을 나누는 방법이 있다. 두 구간화의 차이점은 구간 내 데이터 개수가 유동적인지, 아닌지이다. 별다른 명칭을 찾지 못하겠어서 데이터 기반 구간화라고 하였는데, 해당 방법은 pandas의 cut함수, 등간격 구간화는 qcut함수를 이용하여 구간화를 할 수 있다.

cut함수는 등간격도 지원하고 있지만, bins 매개변수를 통해 구간화 기준을 정해준다. 그렇기 때문에 구간 내 데이터의 개수가 모두 다를 수 있다. 하지만 qcut 함수를 사용하면 다음과 같은 결과가 출력된다.

qcut함수를 사용하게 되면 사진과 같이 데이터의 개수가 동일하게 구간화를 할 수 있다. 

 

점점 난이도가 있는 내용들을 배우고 있지만 뒤쳐지지 않도록
열심히 해야겠다!