순서대로 정렬하기
df.sort_values( )에 정렬 기준으로 삼을 변수를 입력한다.
높은 값에서 내림차순으로 정렬할 시, ascending = False를 입력한다.
exam.sort_values('math') # math 오름차순 정렬
exam.sort_values('math', ascending = False) # math 내림차순 정렬
정렬 기준으로 삼을 변수를 여러 개 지정하려면 [ ] 안에 변수명을 나열하면 된다. 변수별로 정렬 순서를 다르게 지정하려면 ascending에 [ ]를 이용해 값을 입력한다. True를 입력하면 오름차순, False를 입력하면 내림차순으로 정렬한다.
# nclass는 오름차순, math는 내림차순으로 정렬
exam.sort_values(['nclass', 'math'], ascending = [True, False])
# 실습 QUIZ 풀이 (혼자서 해보기)
# mpg 데이터를 이용해 분석 문제를 해결
# 'audi'에서 생산한 자동차 중에서 어떤 자동차 모델의 hwy(고속도로 연비)가 높은지 알아보려고 한다. 'audi'에서 생산한 자동차 중 hwy가 1~5위에 해당하는 자동차의 데이터를 출력하라.
mpg_audi = mpg.query('manufacturer == "audi"')
mpg_audi.sort_values(['hwy'], ascending = False).head()
query( )를 이용해 'audi'에서 생산한 자동차만 추출, sort_values( )로 hwy를 기준으로 내림차순 정렬한다.
1~5위에 해당하는 데이터를 출력하라고 했음으로 head( )를 이용한다.
두 줄의 코드를 한 번에 작성하면 다음과 같이 쓸 수 있다. 결과는 같다.
mpg.query('manufacturer == "audi"').sort_values('hwy', ascending = False).head()
파생변수 추가하기
데이터에 들어 있는 변수 이외에 변수를 조합하거나 함수를 이용해 새 변수를 만들 수 있다.
이때, df.assign( )을 이용하면 파생변수를 생성할 수 있다.
새로 만들 변수명에는 따옴표를 사용하지 않으니 이 점을 주의해야한다.
# total이라는 새로운 변수명에는 따옴표 사용하지 않는다.
exam.assign(total = exam['math'] + exam['english'] + exam['science'])
# 여러 파생변수를 한 번에 추가할 때는 쉼표를 사용하면 된다.
exam.assign(
total = exam['math'] + exam['english'] + exam['science'],
mean = (exam['math'] + exam['english'] + exam['science'])/3)
df.assign( )에 NumPy 패키지의 where( )를 적용하면 조건에 따라 다른 값을 부여한 변수를 추가할 수 있다.
import numpy as np
exam.assign(test = np.where(exam['science'] >= 60, 'pass', 'fail'))
변수를 추가하고 나면 이어지는 pandas 함수에 바로 활용할 수 있다.
# total 변수를 추가하고, sort.values( )를 활용하여 total 변수 기준으로 정렬한다.
exam.assign(total = exam['math'] + exam['english'] + exam['science']).sort_values('total')
df.assign( )을 사용할 때 변수명 앞에 데이터 프레임명을 반복해야한다.
이는 lambda를 이용해 프레임명이 아닌 약어를 입력해 코드를 간결하게 작성할 수 있다.
lambda x : 는데이터 프레임명 자리에 x를 입력하겠다는 의미다.
# 긴 데이터 프레임명 지정
long_name = pd.read_csv('exam.csv')
# long_name 직접 입력할 때의 코드
long_name.assign(new = long_name['math'] + long_name['english'] + long_name['science'])
# lambda를 이용해 간결하게 만든 코드
long_name.assign(new = lambda x : x['math'] + x['english'] + x['science'])
앞에서 만든 파생 변수를 이용해 다시 파생 변수를 만드는 경우, lambda를 이용해 데이터 프레임명을 약어로 입력해야한다.
# 파생변수 total을 가지고 다시 파생변수 mean을 만들 때 lambda를 쓰지 않으면 에러가 출력된다.
exam.assign(total = exam['math'] + exam['english'] + exam['science'],
mean = lambda x : x['total'] / 3)
# 가독성을 위해 파생변수를 만드는 행에 lambda를 각각 입력하면 데이터 프레임명을 통일할 수 있다.
exam.assign(total = lambda x : x['math'] + x['english'] + x['science'],
mean = lambda x : x['total'] / 3)
# 실습 QUIZ (혼자서 해보기)
# mpg 데이터는 연비를 나타내는 변수가 hwy(고속도로 연비), cty(도시 연비) 두 종류로 분리되어 있다. 두 변수를 각각 활용하는 대신 하나의 합산 연비 변수를 만들어 분석하려 한다.
# 1. mpg 데이터 복사본을 만들고, cty와 hwy를 더한 '합산 연비 변수'를 추가하라.
import pandas as pd
mpg = pd.read_csv('mpg.csv')
mpg_new = mpg.copy()
mpg_new = mpg_new.assign(total = mpg_new['hwy'] + mpg_new['cty'])
# 2. 앞에서 만든 '합산 연비 변수'를 2로 나눠 '평균 연비 변수'를 추가하라.
mpg_new = mpg_new.assign(mean = mpg_new['total'] / 2)
# 3. '평균 연비 변수'가 가장 높은 자동차 3종의 데이터를 출력하라.
mpg_new.sort_values('mean', ascending = False).head(3)
# 4. 1~3번 문제를 해결할 수 있는 하나로 연결된 pandas 구문을 만들어 실행하라. 데이터는 복사본 대신 mpg 원본을 이용하라.
mpg.assign(total = lambda x : x['cty'] + x['hwy'],
mean = lambda x : x['total'] / 2) \
.sort_values('mean', ascending = False) \
.head(3)
집단별로 요약하기
각 집단을 요약한 값을 구할 때는 df.groupby( )와 df.agg( )를 사용한다.
df.agg( )에 요약값을 할당할 변수명과 =를 입력한 다음, 값을 요약하는데 사용할 변수와 함수를 괄호 안에 나열한다.
# math 평균 구하기
exam.agg(mean_math = ('math', 'mean'))
▶ 요약값을 할당할 변수명은 df.assign( )을 사용할 때와 마찬가지로 자유롭게 정하고, 따옴표는 입력하지 않는다.
▶ 요약하는데 사용할 변수명과 함수명은 따옴표로 감싸 문자 형태로 입력하고, 함수명 뒤에 ( )를 입력하지 않는다.
집단별로 요약 통계량을 구하고 싶다면 df.groupby( )로 변수를 지정해 변수의 범주별로 데이터를 분리한 다음, agg( )를 적용하면 된다.
# nclass별로 분리하고 math의 평균을 구한다.
exam.groupby('nclass').agg(mean_math = ('math', 'mean'))
출력 결과는 위와 같다. 표의 맨 첫 번째 행이 무엇인가 이상해보인다. 이는 집단을 나타낸 변수명 nclass가 인덱스로 바뀌어 mean_math보다 밑에 표시되었기 때문이다. groupby( )의 기본값이 변수를 인덱스로 바꾸도록 설정되어 있기 때문에 그렇다. df.groupby( )에 as_index = False를 입력하게 되면 변수를 인덱스로 바꾸지 않는다.
+) index : 값이 데이터 프레임의 어디에 있는지 '값의 위치를 나타낸 값' 이다.
exam.groupby('nclass', as_index = False).agg(mean_math = ('math', 'mean'))
여러 요약 통계량을 한 번에 구하고 싶다면 df.assign( )으로 여러 변수를 한 번에 추가하는 것과 마찬가지로 코드를 입력하면 된다.
exam.groupby('nclass') \
.agg(mean_math = ('math', 'mean'),
sum_math = ('math', 'sum'),
median_math = ('math', 'median'),
n = ('nclass', 'count'))
모든 변수의 요약 통계량을 한 번에 구하고 싶다면 df.groupby( )에 agg( ) 대신 mean( )이나 sum( )과 같은 요약 통계량 함수를 적용하면 데이터 프레임에 들어 있는 모든 변수의 요약 통계량을 한 번에 구할 수 있다.
exam.groupby('nclass').mean()
+) agg( )에 자주 사용하는 요약 통계량 함수
함수 | 통계량 |
mean( ) | 평균 |
std( ) | 표준편차 |
sum( ) | 합계 |
median( ) | 중앙값 |
min( ) | 최소값 |
max( ) | 최대값 |
count( ) | 빈도(개수) |
groupby( )에 여러 변수를 지정해 집단을 나눈 다음 다시 하위 집단으로 나눌 수 있다.
# 다음은 제조 회사별로 집단을 나누고 다시 구동 방식별로 나누어 도시 연비 평균을 구한 코드다.
mpg.groupby(['manufacturer', 'drv']) \
.agg(mean_cty = ('cty', 'mean'))
출력 결과에서 drv 행의 개수가 제조 회사별로 다른 이유는 회사마다 생산한 drv 종류가 다르기 때문이다.
# audi는 drv를 2종 생산, chervorlet은 drv를 3종 생산했음을 보여주는 코드
mpg.query('manufacturer == "audi"') \
.groupby(['drv']) \
.agg(n = ('drv', 'count'))
mpg.query('manufacturer == "chervorlet"') \
.groupby(['drv']) \
.agg( n = ('drv', 'count'))
집단별로 빈도를 간단하게 구하고 싶다면 df.value_counts( )를 이용하면 된다. 데이터 프레임에서 빈도를 구할 변수를 추출한 후, value_counts( )를 적용하면 된다.
mpg['drv'].value_counts( )
이는 짧은 코드로 빈도를 구할 수 있고 자동으로 빈도 기준으로 내림차순 된다는 장점이 있지만, 시리즈 자료 구조로 출력하기 때문에 query( )는 적용할 수 없다는 단점이 있다. 이때, 데이터 프레임으로 변환을 해야만 query( )를 사용할 수 있다.
mpg['drv'].value_counts( ) \
.to_frame \
.rename_axis('drv') \
.query('n > 100')
pandas 패키지의 함수들은 하나의 구문으로 조합해 분석 문제를 해결할 수 있다.
예를 들어. 제조 회사별로 'suv' 자동차의 도시 및 고속도로 합산 연비 평균을 구해 내림차순으로 정렬하고, 1~5위까지 출력하는 코드를 작성한다고 하자.
이 코드를 작성하기 위해서는 우선 순위를 정해야한다.
1. suv 추출 - query( )
2. 합산 연비 변수 만들기 - assign( )
3. 회사별 분리 - groupby( )
4. 합산 연비 평균 구하기 - agg( )
5. 내림차순 정렬 - sort_values( )
6. 1~5위까지 출력 - head( )
우선 순위대로 작성한 코드는 다음과 같다.
mpg.query('category == "suv"') \
.assign(total = (mpg['hwy'] + mpg['cty']) / 2) \
.groupby('manufacturer') \
.agg(mean_tot = ('total', 'mean')) \
.sort_values('mean_tot', ascending = False) \
.head()
#실습 QUIZ (혼자서 해보기)
# 1. mpg 데이터의 category는 자동차를 특징에 따라 'suv', 'compact' 등 일곱 종류로 분류한 변수다. 어떤 차종의 도시 연비가 높은지 비교해보려고 한다. catgory별 cty 평균을 구해라.
mpg.groupby('category') \
.agg(mean_cty = ('cty', 'mean'))
# 2. 앞 문제의 출력 결과는 category 값 알파벳순으로 정렬되어 있다. 어떤 차종의 도시 연비가 높은지 쉽게 알아볼 수 있도록 cty 평균이 높은 순으로 정렬해 출력하라.
mpg.groupby('category') \
.agg(mean_cty = ('cty', 'mean')) \
.sort_values('mean_cty', ascending = False)
# 3. 어떤 회사 자동차의 hwy(고속도로 연비)가 가장 높은지 알아보려고 한다. hwy 평균이 가장 높은 회사 세 곳을 출력하라.
mpg.groupby('category') \
.agg(mean_hwy = ('hwy', 'mean')) \
.sort_values('mean_hwy', ascending = False).head(3)
# 4. 어떤 회사에서 'compact' 차종을 가장 많이 생산하는지 알아보려고 합니다. 회사별 'compact' 차종 수를 내림차순으로 정렬해 출력하라.
mpg.query('category == "compact"') \
.groupby('manufacturer') \
.agg(n = ('manufacturer', 'count')) \
.sort_values('n', ascending = False)
# 4번 문제의 코드를 짧게 표현한 코드는 다음과 같다.
mpg.query('category == "compact"') \
.value_counts('manufacturer')
데이터 합치기
1. 가로로 합치기 - pd.merge( )를 이용한다.
① pd.merge( )에 결합할 데이터 프레임명을 나열한다.
② 오른쪽에 입력한 데이터 프레임을 왼쪽 데이터 프레임에 결합하도록 how = 'left'를 입력한다.
③ 데이터를 합칠 때 기준으로 삼을 변수명을 on에 입력한다.
import pandas as pd
test1 = pd.DataFrame({'id' : [1, 2, 3, 4, 5],
'midterm' : [60, 80, 70, 90, 85]})
test2 = pd.DataFrame({'id' : [1, 2, 3, 4, 5],
'final' : [70, 83, 65, 95, 80]})
total = pd.merge(test1, test2, how = 'left', on = 'id')
total
다른 데이터를 활용해 변수를 추가하고 싶다면 pd.merge( )를 활용하면 된다.
name = pd.DataFrame({'nclass' : [1, 2, 3, 4, 5],
'teacher' : ['kim', 'lee', 'park', 'choi', 'jung']})
name
nclass와 teacher 두 변수로 구성되어 있는 name을 exam 데이터 프레임에 추가하면 다음과 같이 출력된다.
exam_new = pd.merge(exam, name, how = 'left', on = 'nclass')
exam_new
nclass 변수 기준으로 두 데이터 프레임이 합쳐진 것이다.
2. 세로로 합치기 - pd.concat( )을 사용한다.
group_a = pd.DataFrame({'id' : [1, 2, 3, 4, 5],
'test' : [60, 80, 70, 90, 85]})
group_b = pd.DataFrame({'id' : [6, 7, 8, 9, 10],
'test' : [70, 83, 65, 95, 80]})
group_all = pd.concat([group_a, group_b], ignore_index = True)
group_all
ignore_index 없이 출력하면 인덱스 0~4가 중복된 형태로 나오게 된다.
데이터를 세로로 합칠 때는 두 데이터의 변수명이 같아야한다. 위 예시처럼 변수가 id, test로 이루어진 데이터 프레임 2개였기 때문에 합칠 수 있었던 것이다. 변수명이 같지 않다면 pd.rename( )을 활용하면 된다.
Reference
김영우, 「DO IT! 쉽게 배우는 파이썬 데이터 분석」, 이지스퍼블리싱, 2022, p. 151-176
'python' 카테고리의 다른 글
[python] 소상공인시장진흥공단 상가업소정보로 프랜차이즈 입점분석 (2) (1) | 2023.01.25 |
---|---|
[python] 소상공인시장진흥공단 상가업소정보로 프랜차이즈 입점분석 (1) (0) | 2023.01.25 |
[python] 데이터 전처리 ① : 변수 추출 (0) | 2023.01.12 |
[python] 데이터 프레임 (1) | 2023.01.08 |
[python] 변수 생성과 함수 (0) | 2023.01.07 |
댓글