-
[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()
'KT 에이블스쿨 복습' 카테고리의 다른 글
[KT 에이블스쿨 5기] DX트랙 3주 3일차 복습_데이터프레임 변경(3) (1) 2024.03.06 [KT 에이블스쿨 5기] DX트랙 3주 2일차 복습_데이터프레임 변경 (1) 2024.03.05 [KT 에이블스쿨 5기] DX트랙 2주 4일차 복습_넘파이 기초, 판다스 데이터 프레임 생성 및 탐색 (3) 2024.03.01 [KT 에이블스쿨 5기] DX트랙 2주 3일차 복습_파일 읽고 쓰기, 엑셀 파일 다루기, 이메일 보내기 (0) 2024.02.29 [KT 에이블스쿨 5기] DX트랙 2주 2일차 복습_함수, 정규표현식 (1) 2024.02.28