ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [KT 에이블스쿨 5기] DX트랙 3주 1일차 복습_판다스 데이터프레임 조회, 집계, 변경
    KT 에이블스쿨 복습 2024. 3. 4. 23:08

    **셀프 복습용으로 작성한 것이라 실수가 있을 수 있습니다!
    혹시 실수를 발견하시면 댓글로 알려주시면 감사드리겠습니다 :)

     

    04 데이터프레임 조회

    보고자 하는 데이터를 즉시 조회할 수 있도록 반복 및 실습!

    라이브러리 불러오기 암기해야 하는 세 가지는 아래와 같음! 

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt

     

     

    특정 열 조회

    데이터를 읽어온 후, df(데이터프레임).loc[: , [열 이름1, 열 이름2,...]] 형태로 조회할 열 이름을 리스트로 지정

    조회할 열이 하나면 리스트 형태가 아니어도 됨! df.loc [ 행 , 열 ] 이 기본값

    열 부분은 생략할 수 있었지만, 행 부분은 생략할 수 없음

    df[[열 이름1, 열이름2,...]] 형태로 인덱서 생략이 일반적

    # total_bill 열 조회
    tip.loc[:,'total_bill']    
    #tip[['total_bill']] 도 가능
    
    # tip, total_bill 열 조회
    tip.loc[:, ['tip', 'tip_bill]]

     

     

    열 범위 조회

    범위 조회는 df.loc[:, 열 이름1:열 이름2] 형태로 조회

    → .loc와 :, 생략 불가능

    범위는 하나만 지정할 수 있어 리스트가 될 수 없으므로 대괄호 사용하지 X

    범위 마지막 열도 조회 대상에 포함  *슬라이싱과 다르게 a[2:5]일 때 2, 3, 4가 나오는 것처럼 n-1이 아님!

     

    조건으로 조회

    1) 단일 조건 조회

    - df.loc[조건] 형태로 조건을 지정해 조건에 만족하는 데이터만 조회할 수 있음

    - 우선 조건이 제대로 판단이 되는지 확인 후 그 조건을 대괄호 안에 작성

    - df.loc [ 행 , 열 ] 에서 행 부분에 조건을 서술
        **why ? → 열 값이 6.0보다 큰 모든 행을 조회하는 것이기 때문

    - 조건을 변수로 선언해 사용할 수도 있음

    # tip 열 값이 6.0 보다 큰 행 조회
    # tip.loc[tip['tip']> 6.0, : ]
    tip.loc[tip['tip']> 6.0]      #뒤에 생략 가능
    
    cond = tip['tip'] > 6.0
    tip.loc[cond]      #cond 뒤 ,: 생략된 형태

     

     

    2) 여러 조건 조회

    - [] 안에 조건을 여러개 연결할 때 and와 or 대신 &와 |를 사용해야 함

    - 그리고 각 조건들은 (조건1) & (조건2) 형태로 괄호로 묶어야 함

    # and로 여러 조건 연결 (tip > 6.0 and day == Sat)
    tip.loc[(tip['tip'] > 6.0) & (tip['day']=='Sat')]
    
    # or로 여러 조건 연결 (tip > 6.0 or day == Sat)
    tip.loc[(tip['tip'] > 6.0) | (tip['day']=='Sat')]

     

    3) 편리한 isin(), between() 메서드

    - isin([값1, 값2, ...., 값n]): 값1 또는 값2 또는 .. 값n인 데이터만 조회

    # 값 나열 (day가 Sat 또는 Sun)
    tip.loc[tip['day'].isin(['Sat', 'Sun'])]
    
    # or 조건 (같은 의미)
    tip.loc[(tip['day'] == 'Sat') | (tip['day'] == 'Sun')]

     

    - between(값1, 값2): 값1 ~값2까지 범위 안의 데이터만 조회 (값1과 값2 모두 포함)

    - 값2 뒤에 메서드 inclusive='both', 'neither', 'left', 'right' 으로 양 끝값 포함 여부를 지정 가능

    # 범위 지정 ( 1 <= size <= 3)
    tip.loc[tip['size'].between(1, 3)]
    
    # and 조건 (같은 의미)
    tip.loc[(tip['size'] >= 1) & (tip['size'] <= 3)]

     

    4) 조건을 만족하는 행의 일부 열 조회

    - df.loc[조건, ['열 이름1', '열 이름2',...]] 형태로 조회할 열을 리스트로 지정

    # 조건에 맞는 하나의 열 조회
    tip.loc[tip['size'] >= 5, ['tip']]
    
    # 조건에 맞는 여러 열 조회
    tip.loc[tip['size'] >= 5, ['total_bill', 'tip', 'size']]

     

    조회 정리 df.loc[행 정보, 열 정보]

    조회 코드 예
    특정 열 df.loc[:, 'score'] → df['score']
    여러 열 df.loc[:, ['name', 'score']] → df[['name', 'score']]
    특정 행 df.loc[1, :] → df.loc[1]    **df[1]: 열 이름이 1인 데이터를 추출하게 됨!
    여러 행 df.loc[[1, 3, 5], :] → df.loc [[1, 3, 5]]
    특정 조건 df.loc[(df['score'] >= 80, :] → df.loc[(df['score'] >= 80] 
    여러 조건 df.loc[(df['score'] >= 80) & (df['age'] < 20), :] → df.loc[(df['score'] >= 80) & (df['age'] < 20) ] 
    여러 조건 특정 열 df.loc[(df['score'] >= 80) & (df['age'] < 20), ['name', 'age', 'score']]
    between() df.loc[(df['score'].between(80, 90), :] df.loc[(df['score'].between(80, 90)]
    isin() df.loc[(df['grp'].isin(['A1', 'B3', 'C1']), :] df.loc[(df['grp'].isin(['A1', 'B3', 'C1'])]

     

    - 굵게 표시된 코드형태로 조회!

     

    인덱스 초기화

    다음과 같은 경우 인덱스 초기화가 필요

    - 기존 데이터프레임에서 일부 행을 가져와 새로 만든 데이터프레임

    - 일부 행이 지워진 데이터 프레임

    특히 0부터 시작하는 정수형 인덱스의 경우 초기화를 하는 것이 좋음!

     

    - reset_index() 메서드로 인덱스를 초기화합니다.
    - 기존 인덱스 값은 의미가 없으므로 drop=True 옵션을 지정해 제거, inplace=True 옵션을 지정

     

     

    05 데이터프레임 집계

    상세 데이터가 아닌 집계된 데이터에 대한 분석을 자주 요구!

    sum(), mean(), max(), min(), count() 메서드를 사용해 지정한 열 또는 열들을 기준으로 집계

    주요 역할 집계값 비고 구분
    - total_bill
    - tip
    집계 대상 열 - 합
    - 평균
    - 최댓값
    - 최솟값
    - 대부분 집계 대상 열이 됨
    - 예: tip 평균
    연속값
    - sex
    - smoker
    - day
    - time
    - size
    집계 기준 열 - 개수
    - 최빈값
    - 대부분 집계 기준이 됨
    - day별, time별 등
    - 예: day별 tip 평균
    범주값

     

    연속값, 범주값이라는 용어에 익숙해지자! 대부분은 범주값을 기준으로 연속값의 합, 평균 등을 집계

    가끔 범주값의 개수나 최빈값을 집계하기도 함

    - 범주형 값을 갖는 특정 열이 어떤 값을 몇 개 가지고 있는지 확인하려면 df['열 이름'].value_counts()

     

    합 구하기

    열 하나 집계

    우선 특정 열의 값 합은 .sum()을 통해 구함

    # total_bill 합계
    tip[['total_bill','tip']].sum()
    # total_bill, tip 각각의 합계
    tip[['total_bill','tip']].sum()

     

    1) 집계하기

    - day 별로 합을 구하고자 한다면, 아래처럼 작성

    - as_index = True를 설정(기본값)하면 집계 기준이 되는 열이 인덱스 열이 됨!
      **as_index=False를 설정하면 데이터프레임이 됨! (by='day'가 열이 되어야 하기 때문)

      **[['tip']].sum()으로 쓰면 열이 여러개라는 의미애서 결과가 데이터프레임이됨!

    - 집계 결과가 tip 열만 있으면 시리즈가 됨

    # day별 tip 합계 --> 시리즈, by= 생략 가능
    tip.groupby(by='day', as_index=True)['tip'].sum()

     

    2) 데이터프레임으로 선언

    - 집계 결과를 새로운 데이터프레임으로 선언해 사용

    - 집계된 결과를 반복해 사용하거나, 분석 대상이 되는 경우 데이터프레임으로 선언이 좋음

    # day별 tip 합계 조회
    tip_sum = tip.groupby(by='day', as_index=False)[['tip']].sum()
    
    # 확인
    tip_sum

     

    3) 집계 결과 시각화

    - 위 과정으로 집계한 결과를 막대그래프로 간단히 시각화

    - matplotlib 패키지의 pyplot을 plt 별칭을 주고 불러와 시각화에 사용

    # 라이브러리 불러오기
    import matplotlib.pyplot as plt
    %config InlineBackend.figure_format='retina'            # 축 이미지 고해상도로 변환
    
    # day 별 tip 비교 시각화
    plt.rc('axes', axisbelow=True)                   #막대선 뒤로 숨기기
    plt.figure(figsize=(8, 5))                            # 이미지 사이즈 설정
    plt.bar(x=tip_sum['day'], height=tip_sum['tip'])
    plt.title('Tip by Day', pad=15, size=15, fontweight='bold')              # 타이틀, 타이틀-이미지 사이 여백, 폰트 사이즈, 볼드체
    plt.xlabel('Day')                                     # x축 이름
    plt.ylabel('Tip($)')                                  # y축 이름
    plt.grid(axis='y')
    plt.show()

    - 위와 동일한 그래프를 가로 막대그래프로도 표현 가능 plt.barh()를 활용

    # day 별 tip 비교 시각화
    plt.figure(figsize=(5,3))
    plt.barh(y=tip_sum['day'], width=tip_sum['tip'])
    plt.xlabel('Tip')
    plt.ylabel('Day')
    plt.show()

     

    4) 참고: 선 그래프

    - 연속형 값의 변화 추이를 볼 때 선 그래프가 유용

    # tip 변경 추이 시각화
    plt.figure(figsize=(5,3))
    plt.plot(tip['tip'])
    plt.show()

     

    # tip, total_bill 변경 추이 시각화
    plt.figure(figsize=(5,3))
    plt.plot(tip[['tip', 'total_bill']])
    plt.legend(['tip', 'total bill'])           #범례 추가
    plt.show()

    5) 참고: 히스토그램

    - 연속형 값의 분포를 볼 때는 히스토그램이 유

    # tip 분포 시각화
    plt.figure(figsize=(5,3))
    plt.hist(tip['tip'])
    plt.show()

    # total_bill 분포 시각화
    total_bill_mean = tip['total_bill'].mean()
    print(total_bill_mean)
    plt.figure(figsize=(5,3))
    plt.hist(tip['total_bill'], bins=20, alpha=0.7, edgecolor='w')   #그래프의 세부 디테일 설정
    plt.axvline(total_bill_mean, color='tab:orange')    #평균에 수직선 그리기, 색 설정
    plt.show()

     

     

    여러 열 집계

    여러 열에 대한 집계를 같이 할 수 있음!

    - [ ['total_bill', 'tip'] ].sum() 형태로 집계 대상 열을 리스트로 지정

    - sum() 메서드 앞에 아무 열도 지정하지 않으면 기준열 이외의 모든 열에 대한 집계 수행!

    - numeric_only=True를 설정하면 숫자 열에 대해서만 집계

    # day별 나머지 열들 합계 조회
    tip_sum = tip.groupby(by='day', as_index=False).sum(numeric_only=True)
    
    # 확인
    tip_sum

    → sum앞에 열을 서술하지 않았으므로, 기준열 이외 모든 열에 대한 집계 결과 출력됨!

     

    by=['day', 'smoker']과 같이 집계 기준 열을 여러 개 설정할 수도 있음!

    # day + smoker별 나머지 열들 합계 조회
    tip_sum = tip.groupby(by=['day','smoker'], as_index=False).sum(numeric_only=True)
    
    # 확인
    tip_sum

     

     

    평균, 최댓값, 최솟값, 개수 구하기

    1) 평균 구하기

    - tip_mean = tip.groupby(by='day', as_index=False)[['tip']].mean()

    2) 최댓값 구하기

    - tip_mean = tip.groupby(by='day', as_index=False)[['tip']].max()

    3) 최솟값 구하기

    - tip_mean = tip.groupby(by='day', as_index=False)[['tip']].min()

    4) 개수 구하기

    - tip_mean = tip.groupby(by='day', as_index=False)[['tip']].count()

     

     

    06 데이터프레임 변경 (1)

    데이터 전처리를 위해 꼭 알아두어야 함!

     

    열 이름 변경

    1) 일부 열 이름 변경- rename() 메서드를 사용해 변경 전후의 열 이름을 딕셔너리 형태로 나열- inplace=True 옵션을 설정해야 변경 사항이 실제로 반영

    titanic.rename(columns={'Sex':'Male'}, inplace=True)

     

    2) 모든 열 이름 변경- 모든 열 이름을 변경할 때는 .columns = [리스트] 형태로 속성을 변경- 변경이 필요없는 열은 기존 이름을 부여해 변경

    # 모든 열 이름 변경:
    # ['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size']
    tip.columns = ['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size']
    
    # 확인
    tip.head(2)

     

     

    열 추가

    새로운 열을 추가해 기존 데이터에서 계산된 결괏값을 저장해야 할 때!

    # final_amt 열 추가: final_amt = total_bill + tip
    tip['final_amt'] = tip['total_bill'] + tip['tip']
    
    # 확인
    tip.head()

     

    - insert() 메서드를 사용하면 원하는 위치에 열을 추가 가능!

    - df.insert(loc, column, value, allow_duplicates=False))

    loc: 열이 추가될 위치

    column: 추가할 열의 이름

    value: 값

    allow_duplicates: 중복 가능 여부

    # tip 열 앞에 div_tb 열 추가: div_tb = total_bill / size
    tip.insert(1, 'div_tb', tip['total_bill'] / tip['size'])
    
    # 확인
    tip.head()

     

    **어려웠던 예제풀이

    - day가 Sat, Sun 이면 1, 나머지는 0 값을 갖는 holiday 열을 추가하세요.

    # 범주값 확인으로 값에 목금토일만 있는 것을 확인
    tip['day'].value_counts()
    # holiday 열 추가
    tip['holiday'] = 0   #범주값 확인했을 때 목금토일밖에 없으니, 일단 모두 0으로 열 추가 입력
    tip.loc[tip['day'].isin(['Sat', 'Sun']), 'holiday'] = 1
    tip.loc[(tip['day']=='Sat')|(tip['day']=='Sun'), 'holiday'] = 1
    
    # 확인
    tip['holiday'].value_counts()

     

Designed by Tistory.