본문 바로가기

TIL

[240124-26] 데이터 전처리 & 시각화

[데이터 전처리 & 시각화 by 박성원 튜터]

 

00. 데이터 분석가란?

1) 데이터 분석가 유형 

- 비즈니스 분석가 (Business Analyst, BA)
 : 주로 비즈니스 문제를 이해하고 해결하기 위해 데이터를 분석
 : 비즈니스 프로세스 및 요구 사항을 파악하고, 데이터 기반으로 의사 결정을 지원
 : 주로 업무 프로세스 개선, 비즈니스 모델 분석, 요구 사항 관리 등을 수행
- 프로덕트 분석가 (Product Analyst, PA)
 : 제품이나 서비스의 성과를 평가하고 개선하기 위해 데이터를 분석
 : 사용자 행동 및 제품 성능과 관련된 데이터를 분석하여 제품 개선에 기여
 : 주로 제품 경험과 사용자 행동에 대한 분석을 수행하며, A/B 테스트, 사용자 경로 분석 등을 담당

- BI 분석가
 : 기업의 비즈니스 인텔리전스 플랫폼과 도구를 사용하여 데이터를 시각화하고 보고서를 작성
 : 주로 기업 내부 데이터를 시각화하고, 이를 통해 의사 결정에 필요한 정보를 제공
 : BI 도구 (Tableau, Power BI 등)를 사용하여 대시보드를 구축하고, 데이터 시각화 및 보고서 작성

- 데이터 분석가
 : 주로 정형 데이터를 분석하여 기업 의사 결정을 지원
 : 데이터베이스, 스프레드시트 등에서 데이터를 추출하고, 이를 정제하여 보고서 및 시각화 생성
 : 주로 기술적인 기술이 필요하며, SQL, Excel, 데이터 시각화 등을 활용하여 업무를 수행

- 데이터 사이언티스트
 : 주로 데이터를 활용하여 예측, 패턴 발견, 복잡한 분석을 수행하여 비즈니스 문제 해결
 : 통계, 머신러닝, 딥러닝 등의 기술과 알고리즘을 사용하여 데이터를 분석하고 모델을 구축
 : 데이터 수집, 전처리, 모델링, 평가 및 해석을 포함한 A to Z 데이터 분석 작업을 수행 

2) 데이터 전처리와 시각화가 필요한 이유 

- 데이터의 목적은 결국 설득! 

: 설득을 잘 하기 위해서는 데이터를 잘 전달해야 하고, 이를 위해 '시각화'가 필요한 것

- 데이터 전처리와 시각화는 목적이 중요! 

: 데이저 전처리는 데이터를 전달하기 위한 목적성이 필수이며, 목적성이 있을 때 데이터 전달의 효과성이 증가 

: 데이터를 어떤 목적을 가지고, 어떻게 분석할 것인가 미리 설계가 필요함 

 

(분석 설계 예시)
① 목표 설정하기: 무엇을 위해 데이터 전처리와 시각화가 필요한가?
② 예상 산출물 정의하기: 데이터 처리 및 시각화를 통한 예상 결과물은 무엇인가?
③ As-is vs. To-be 생각하기: 현재 문제 상황이 무엇이고, 어떻게 개선할 것인지 생각하며 분석 방향성을 설정하기

 

(연습하기)

- https://dataitgirls2.github.io/10minutes2pandas/

- https://pandas.pydata.org/pandas-docs/stable/user_guide/10min.html

 


01. 데이터 전처리(Pandas)

0) 데이터 전처리란?

- 원하는 데이터를 보기 위해 하는 모든 활동

- 데이터 전처리는 달성하고자 하는 목표가 무엇인지와 같은 방향성이 꼭 있어야 함 

 

(cf) Excel vs Pandas

[Pandas]
- 대규모 데이터셋 및 복잡한 작업 처리에 효과적
- 자동화와 프로그래밍 기능을 통해 더 많은 유연성과 확장성 제공

[엑셀]
- 상대적으로 작은 규모의 데이터나 간단한 작업에 유용
- 비전문가가 쉽게 사용할 수 있는 직관적인 인터페이스 제공

더보기

1. 자동화와 프로그래밍 기능
 · Pandas: 다양한 라이브러리를 사용한 데이터 불러오기, 변환, 분석이 가능해 반복적이고 복잡한 작업 자동화 가능

 · 엑셀: 주로 수동으로 작업이 수행되며, 고급 기능을 프로그래밍적으로 확장하기가 어려움


2. 대용량 데이터 처리
 · Pandas: 대용량 데이터 처리에 유용. 메모리 내 데이터 처리 및 데이터 세트 조각으로 나누어 처리하는 기능 제공

 · 엑셀: 상대적으로 작은 데이터 처리에 적합. 큰 데이터는 처리 속도 저하나 용량 제한 등 제약이 생기기도 함


3. 복잡한 데이터 처리 및 분석
 · Pandas: 다양한 도구와 라이브러리를 활용해 복잡한 데이터 작업, 통계 분석, 머신러닝 모델 구축 등 가능
 · 엑셀: 기본적인 수식과 함수를 통해 데이터 처리 및 시각화 가능하나 복잡한 데이터 조작이나 분석엔 제약이 있음


4. 확장성과 유연성
 · Pandas: 다양한 데이터 포맷 처리나 데이터베이스 연동 작업 등 유연성이 높음 
 · 엑셀: 주로 특정 데이터 형식의 파일(.xlsx, .csv 등)을 다루는 데에 제한


5. 버전 관리 및 자동화
 · Pandas: 버전 관리 시스템으로 Python 코드 변경 내역을 관리하고, 코드 주석을 활용해 작업 히스토리 추적 가능

· 엑셀: 사용자가 직접 수정하기 때문에 변경 사항을 추적하거나 문서화하기 어려움 

1) Pandas란?

- 기본 개념: Python에서 데이터를 조작하고 쉽게 분석할 수 있게 도와주는 라이브러리

- Pandas의 구조 

 

- Series = index + values

 └ 하나의 속성을 가진 데이터 집합 (DataFrame 표에서 열(column) 1줄이라고 생각하면 쉬움)

- DataFrame = index  + column
 └ 컬럼이 2개 이상 있는 표 형태의 데이터 집합 

 └ index: 각 아이템을 특정할 수 있는 고유의 값 (엑셀에서는 좌측 열순서로 생각하면됨)
 └ columns: 하나의 속성을 가진 데이터 집합

 

 

2) 데이터 불러오기/저장하기

① 데이터 불러오기

# 엑셀 불러오기
    pd.read_excel('파일경로/파일명.xlsx') 
# csv 파일 불러오기	
    pd.read_csv('파일경로/파일명.csv')
    
#파일이 깨져서 불러와진다면? 인코딩 방식 지정이 필요할 때도 
    data = pd.read_csv('file.csv', encoding='utf-8')
    data = pd.read_csv('file.csv', encoding='ascii')

 

▶ 인덱스(Index)
- 의미: 데이터프레임(DataFrame) 또는 시리즈(Series)의 각 행 또는 각 요소에 대한 식별자
  └ 기본적으로 0부터 시작하는 숫자로 자동 지정되나 임의로 문자 형태로 적용도 가능 
  └ 처음 파일 불러올 때 인덱스를 지정하거나 제외하는 것도 가능함

 

- 인덱스 특징
  (1) 고유성(Uniqueness): 각 행은 유일한 인덱스 값을 가지며, 중복된 값을 가질 수 없음
  (2) 불변성(Immutability): 한 번 생성된 인덱스는 변경(수정) 할 수 없으며, 새로운 값을 할당해 기존 인덱스 대체 가능
  (3) 조작 및 탐색(Manipulation and Retrieval): 인덱스로 데이터프레임 또는 시리즈의 특정 행을 선택 및 탐색 가능
  (4) 정렬(Sorting): 인덱스를 기준으로 데이터프레임 또는 시리즈의 행 정렬 가능

 

- 인덱스 예시 

  (1) 기본 인덱스: 각 행은 유일한 인덱스 값을 가지며, 중복된 값을 가질 수 없음
  (2) 사용자 지정 인덱스: 사용자가 직접 인덱스를 설정

-- (1) 기본 인덱스: Pandas는  0부터 시작하는 정수 인덱스 자동 생성

# 기본 정수 인덱스를 가진 데이터프레임 생성
	df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']})

-- (2) 사용자 지정 인덱스: 사용자가 직접 인덱스 설정

# 직접 인덱스를 설정한 데이터프레임 생성
	df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']}, index=['idx1', 'idx2', 'idx3'])

#리스트 형태를 활용해서 인덱스 생성
	df.index = ['1번' , '2번' , '3번']

 

- 인덱스 활용

#인덱스 확인하기
    data.index

# 특정 인덱스 행에 접근
    row = df.loc['idx2']

# 인덱스를 기준으로 데이터프레임 정렬
    sorted_df = df.sort_index()

# 특정 칼럼 > 인덱스로 변경 
    data = df.set_index('컬럼명')

    # 파일 불러올때 특정 칼럼을 인덱스로 지정하기
    pd.read_csv('./data/file.csv' , index_col = '컬럼정보') 
    pd.read_csv('./data/file.csv' , index_col = 0) # 0부터 시작

# 인덱스 > 칼럼으로 변경 (0부터 시작하는 정수로)
    data.reset_index()
    
    # reset_index() 기본 값은 drop = False로 현재 인덱스값 > 칼럼으로 초기화
    # reset_index(drop = True) 현재 인덱스는 칼럼으로 변경 안되고(사라지고) 정수 인덱스로 초기화

 

▶ 컬럼(Column)
- 의미: 행과 열로 구성된 데이터프레임의 열(또는 변수)에 해당. 각 열은 서로 다른 종류의 데이터를 담고 있음 

- 컬럼의 특징
  (1) 고유한 이름(라벨)을 가지고 있어, 해당 컬럼 데이터를 식별하는 데 사용
  (2) 시리즈(Series) 객체로 구성되어 있으며, 시리즈는 동일한 데이터 유형을 가진 1차원 배열과 유사함
  (3) 숫자, 문자열, 날짜 등 다양한 데이터 유형 중 특정한 유형의 데이터를 포함하며 경우에 따라 유형 변경 가능 

 

- 컬럼 활용

#컬럼 확인하기
    data.column

#파일 불러올 때 컬럼명 변경하기 
    pd.read_csv('./data/file.csv' , names = [’컬럼명1’, ‘컬럼명2’, … ,‘컬럼명 19’])

#리스트 형태로 컬럼명을 변경하기 
    data.column = ['축구', '농구', '배구', '야구']

 

② 데이터 저장하기

df = 데이터프레임 # 저장하고 싶은 데이터
df.to_csv('파일경로/파일명.csv', index = False)

 

 

3) 데이터 확인

① 데이터 확인

▶.head() : 데이터를 N개 행까지 보여줌 
▶.Info() : 데이터의 정보를 한 눈에 파악(인덱스, 컬럼명, 컬럼의 데이터 개수, 데이터 타입 등). null 값 파악에 용이

  └ 결측치(null) 여부, 데이터 타입이 적절한지 등 체크 필요 
▶.describe() : 숫자 데이터에 대한 기초통계량 확인(개수, 평균, 표준편차, 사분위, 중앙값 등)
 └ 목적에 따라 필요한 통계치도 미리 확인 필요 

 

② 데이터 타입 변경

▶ 데이터 타입 종류

데이터 타입(Data Type) 함수 명칭  설명(Description) 예시(Example)
int64, int32 int 정수형 데이터 (64비트 또는 32비트) 1, 42, -10, 1000
float64, float32 float 부동 소수점 수 (64비트 또는 32비트) 3.14, -0.001, 2.718
object str 문자열 데이터 (일반적으로 문자열) 'Hello', 'Data Science'
bool bool 불리언(참/거짓) 데이터 True, False
datetime64 datetime 날짜와 시간 데이터 '2023-12-31 08:00:00'
timedelta64 timedelta 시간 간격(두 날짜 또는 시간 사이의 차이) 데이터 '3 days', '2 hours'
category 'category' 카테고리형 데이터 (제한된 고유 값으로 구성) 'Red', 'Blue', 'Green'

 

astype() : Pandas 데이터프레임의 열 데이터 타입을 원하는 형식으로 변환 할 수 있는 메소드

#부동소수점 타입으로 변환
    df['column'] = df['column'].astype(float) 
# 문자열 타입으로 변환
    df['column'] = df['column'].astype(str)

 

 

4) 데이터 선택

① 데이터 슬라이싱(lioc, loc)

▶  .iloc[행번호(로우),열번호(컬럼)] : 정수 형태의 행과 칼럼 번호로 선택

* iloc로 범위 지정 시 [x:n,x:n] 에서 x는 행과 열의 위치 시작값이고, n은 0부터 시작해서 마지막값으로 이해

#한 개의 데이터 선택
    data.iloc[0,2] # 인덱스 0의 행과 2의 열 값 선택

#특정 행과 열 선택
    df.iloc[1:4, 0:2]  # 인덱스 1부터 3까지의 행과 0부터 1까지의 열 선택

 

.iloc[행이름(로우),열이름(컬럼)] : 문자 형태의 행과 칼럼 이름으로 선택 

#한 개의 컬럼 선택
    data.loc[: , '컬럼명'] #특정 열 데이터 선택

    data['컬럼명']  #data.loc[: , '컬럼명']와 동일한 결과값
    data[   ['컬럼명3', '컬럼명1', '컬럼명2' ]   ]  #원하는 순서로 다수 칼럼 지정 가능

#특정 행과 열 선택
    #2개 컬럼명을 선택할 경우
    data.loc[  '행이름'  , ['컬럼명1' , '컬럼명2']   ]

    # 2개 행이름을 선택할 경우
    data.loc[  ['행이름1', '행이름2'] , '컬럼명1'    ]

    # 리스트 슬라이싱 : 을 활용해서 특정 범위를 지정하여 선택할 수 있습니다.
    data.loc[ '행이름' , '컬럼명1' : ] #'컬럼명1' : ==> 컬럼명1부터 끝까지

 

②  조건에 따른 데이터 선택 (Boolean Indexing)

▶ Boolean Indexing이란?
 - 조건을 이용해 데이터프레임에서 특정 조건을 만족하는 을 필터링 및 추출하는 방법

 - 주로 불리언(Boolean) 값을 가지는 조건식을 사용하여 데이터프레임을 인덱싱하는 방법
  └ 조건식에 따라 각 행이 True 또는 False로 평가되며 이를 바탕으로 데이터프레임을 필터링

 

▶ Boolean Indexing 사용 방법

# 1. 단일 조건으로 필터링: 열의 값을 특정 기준으로 필터링 
    # 'age' 열에서 30세 이상인 행 필터링
    df[df['age'] >= 30]
    #조건을 통해 True/False가 된 값에서 True에 해당하는 값만 반환
    condition = data['컬럼명1'] < 80

# 2. 여러 조건으로 필터링: 여러 개의 조건을 조합하여 복합적으로 필터링
    # 'age' 열에서 30세 이상이면서(and) 'gender' 열이 'Male'인 행 필터링
    # 각 조건에 () 소괄호 추가 
    df[(df['age'] >= 30) & (df['gender'] == 'Male')]
    
    #조건을 변수로 만들어서 간결하게 활용도 가능 
    condition1 = df['age'] >= 30
    condition2 = df['gender'] == 'Male'
    condition = condition1 & condition2 #and
    condition = condition1 \ condition2 #or
    
# 3. 조건에 따른 특정 컬럼 필터링: 조건을 만족하는 특정 열만 선택
    # 'age' 열에서 30세 이상인 경우의 'name' 열만 선택
    df.loc[df['age'] >= 30, 'name']

# 4. isin()을 활용한 필터링: 리스트를 활용해 여러 값들을 포함하는 행 필터링 
    # 'gender' 열에서 'Male' 또는 'Female'인 행 필터링
    df[df['gender'].isin(['Male', 'Female'])]

 

▶ isin() 매소드

 - Series(시리즈)나 DataFrame(데이터프레임)의 값들 중에서 특정 값이나 리스트 안에 포함된 값들을 찾아내는 메소드. 

 - 원하는 조건에 해당하는 데이터를 빠르게 필터링하거나 선택할 수 있음

# 1. 단일 값 포함 여부 확인
    # 'B' 열에서 'banana' 값이 있는지 확인
    result = df['B'].isin(['banana'])

# 2. 여러 값 포함 여부 확인
    # 'A' 열에서 2 또는 4 값을 포함하는 행 찾기
    result = df['A'].isin([2, 4])

# 3. 데이터프레임 전체에서 사용
    # 데이터프레임 전체에서 여러 조건을 확인하여 필터링
    result = df.isin({'A': [1, 3], 'B': ['apple', 'orange']})

 

(cf) 줄바꿈이 필요하다면? 

#역슬래시(\) + Enter로 줄바꿈 가능
condition = (data['컬럼명1'] < 80) \
					& (data['컬럼명2'] >= 50)\
					& (data['컬럼명3'] >= 10)

 

③ 데이터 추가

df = pd.DataFrame()

# 신규 칼럼 추가
    df['컬럼명'] = data

# 리스트 형태로 컬럼값 추가
    df['KFC_menu'] = ["치킨"]  # 칼럼값이 1개면 전체 칼럼에 1개의 값이 전체 적용 
    df['KFC'] = [50, 10, 30] # 행 수에 맞춰 입력 필요 (입력 순서대로 들어감) 
    
# 여러 조건 및 계산식을 통한 산출 값으로 칼럼 추가
    df['ABC'] = (df['EPL'] + df['NBA']) * df['MLS'] * 2

 

 

5) 데이터 병합

① concat

- pd.concat() 과 같이 사용 

- concat()함수는 데이터프레임을 위아래로 혹은 좌우로 연결

 └ axis: 연결하려는 축(방향) 지정. 기본값 axis = 0은 위아래(행)로 연결, axis = 1로 별도 설정하면 좌우(열)로 연결

 └ ignore_index:기본값은 False로 기존 인덱스 유지. True하면 기존 인덱스를 무시하고 새로 인덱스 설정

# 두 개의 데이터프레임 생성
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'], 'B': ['B0', 'B1', 'B2']})
df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'], 'B': ['B3', 'B4', 'B5']})

# 위아래로 데이터프레임 연결
result_vertical = pd.concat([df1, df2], axis=0)

# 좌우로 데이터프레임 연결
result_horizontal = pd.concat([df1, df2], axis=1)

print("위아래 연결 결과:\n", result_vertical)
print("\n좌우 연결 결과:\n", result_horizontal)

 

② merge 

- pd.merge() 와 같이 사용 

- 주로 두 개 이상의 데이터프레임에서 공통된 열이나 인덱스 기준으로 데이터를 좌우 병합할 때 활용

- 주요 매개 변수

 └ left와 right: 병합할 데이터프레임 중 병합 기준이 왼쪽(left)과 오른쪽(right). 생략 시 left, right 순으로 병합
 └ on: 병합 기준이 되는 열 이름(혹은 열 이름의 리스트) 지정

     · left_on과 right_on: 왼쪽 데이터프레임과 오른쪽 데이터프레임에서 병합할 열 이름이 다른 경우 사용

 └ how

     · inner: 공통된 키(열)를 기준으로 교집합

     · outer: 공통된 키(열)를 기준으로 합집합

     · left: 왼쪽 데이터프레임의 모든 행을 포함하고, 오른쪽 데이터프레임은 공통된 키에 해당하는 행만 포함

     · right: 오른쪽 데이터프레임의 모든 행을 포함하고, 왼쪽 데이터프레임은 공통된 키에 해당하는 행만 포함

# 'key' 열을 기준으로 두 데이터프레임 병합
merged_df = pd.merge(left_df, right_df, on='key', how='inner')

 

 

6) 데이터 집계

① Group by

- 데이터프레임.groupby('컬럼명').집계함수() 와 같이 사용 
- 데이터프레임을 그룹화하고, 그룹 단위로 데이터를 분할(split), 적용(apply), 결합(combine)하는 기능 제공
- 특정 기준에 따라 데이터프레임을 그룹으로 나누어 집계, 변환, 필터링 등을 하고 새로운 데이터프레임 생성 
 └ 그룹 생성: 기준 열(혹은 열들)을 지정하여 데이터프레임을 그룹으로 분할
 └ 그룹에 대한 연산 수행: 그룹 단위로 원하는 연산(평균, 합, 개수 등)을 수행 
 └ 결과 결합: 각 그룹의 연산 결과를 하나의 데이터프레임으로 결합하여 새로운 데이터프레임을 생성 

df = pd.DataFrame(data)

#하나의 열 기준으로 집계 함수 활용
    grouped = df.groupby('Category').mean()
    grouped_max = df.groupby('Category').max()

#복수의 열 기준으로 집계 함수 활용
    grouped_multiple = df.groupby(['Category', 'SubCategory']).sum()

#복수의 열 기준으로 복수의 집계 함수 활용
    #agg() 함수로 여러 집계 함수 적용 가능 
    grouped_multiple = df.groupby(['Category', 'SubCategory']).agg({'Value1': ['mean', 'sum'], 'Value2': 'sum'})

 

② Pivot Table

- pivot_table(): 함수는 데이터프레임에서 피벗 테이블*을 생성하는 데 사용
    * Pivot Table란? 데이터를 재구성하여 요약, 집계된 정보를 보기 쉽게 보여주는 테이블 형태

# 샘플 데이터프레임 생성
    data = {
        'Date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02', '2023-01-01'],
        'Category': ['A', 'B', 'A', 'B', 'A'],
        'Value1': [10, 20, 30, 40, 50],
        'Value2': [100, 200, 300, 400, 500]
    }
    df = pd.DataFrame(data)

# 피벗 테이블 생성
# aggfunc 포함 모든 변수 넣을 때 작은 따옴표 추가     
    # 하나의 열 기준으로 피벗 테이블 생성  
    # 날짜를 행 인덱스로, 카테고리를 열 인덱스로, 값은 'Value1'의 합으로 집계
    pivot = df.pivot_table(index='Date', columns='Category', values='Value1', aggfunc='sum')

    # 여러 열 기준으로 피벗 테이블 생성
    # 'Date'를 행 인덱스로, 'Category'와 'SubCategory'를 열 인덱스로, 값은 'Value1'의 합으로 집계
    pivot = df.pivot_table(index='Date', columns=['Category', 'SubCategory'], values='Value1', aggfunc='sum')
    
    # 집계 함수를 다르게 적용하여 피벗 테이블 생성
    pivot = df.pivot_table(index='Date', columns='Category', values=['Value1', 'Value2'], aggfunc={'Value1': 'mean', 'Value2': 'sum'})

 

③ 데이터 정렬하기

▶ sort_values() 함수: 컬럼 기준으로 정렬

▶ sort_index() 함수: 인덱스를 기준으로 정렬

df = pd.DataFrame(data)

# sort_values: 'Score' 열 기준
    sorted_by_score = df.sort_values('Score') #오름차순
    sorted_by_score = df.sort_values('Score',ascending=False) #내림차순

# sort_index: 인덱스 기준
sorted_by_index = df.sort_index() #오름차순 
sorted_by_index = df.sort_index(ascending=False) #내림차순

 

 

7) 기타: pickle

▶ pickle 활용하기
 - python 의 변수, 함수, 객체를 binary형태 파일로 저장하고 불러올 수 있는 라이브러리
 - list, dictionary 등을 파일 그대로 저장하면 용량이 매우 커지는데 pickle을 사용 시 용량 감소(binary 역할)
 - 추가적으로 gzip을 이용하여 pickle로 저장된 데이터 압축 가능 
  : pandas에서는`to_pickle()`및`read_pickle()` 메서드를 통해 `pickle`을 사용할 수 있음
- 머신러닝 모델 등을 저장하고 불러올 때도 활용

df = pd.DataFrame(data)

# 데이터프레임을 pickle 파일로 저장
df.to_pickle('파일명.pkl')

# pickle 파일에서 데이터프레임 불러오기
loaded_df = pd.read_pickle('파일명.pkl')

 

[실습하기]

더보기

1) iris 데이터셋 활용 전처리

import seaborn as sns

# 데이터셋 불러오기
iris_data = sns.load_dataset('iris')

# Q1. 'species' 열 값이 'setosa'인 데이터 선택하기
    #내정답 #isin 쓴 건 데이터프레임[리스트]로 넣어줘야 함 
    setosa_data = iris_data[iris_data['species'].isin(['setosa'])]  
    #정답코드 #loc 활용. == 으로 조건을 걸고 loc로 추출 가능 
    setosa_data = iris_data.loc[iris_data['species'] == 'setosa'] 
    
# Q2. 10부터 20까지의 행과 1부터 3까지의 열 선택하기 
    select_data = iris_data.iloc[10:21, 1:4]   #n까지 행에 +1 더하기

 

2) tip 데이터셋 활용 전처리

## tip 데이터셋 활용 전처리
import pandas as pd
import seaborn as sns

# 데이터셋 불러오기
tips_data = sns.load_dataset('tips')
tips_data

# Q1. total_bill이 30 이상인 데이터만 선택하기
    high_bill = tips_data.loc[tips_data['total_bill'] >= 30]  #.loc는 빼도 무방 
    high_bill

# Q2. 성별('sex')을 기준으로 데이터 그룹화하여 팁(tip)의 평균 계산
    tip_by_gender = tips_data.groupby('sex')['tip'].mean()
    # tip_by_gender = tips_data.groupby('sex').agg({'tip': ['mean']})
    tip_by_gender

# Q3. 'day'와 'time'을 기준으로 데이터 그룹화하여 전체 지불 금액(total_bill)의 합 계산
    bill_by_dayntime = tips_data.groupby(['day', 'time'])['total_bill'].sum()
    # bill_by_dayntime = tips_data.groupby(['day', 'time']).agg({'total_bill': ['sum']})
    bill_by_dayntime 

# Q4. 'day' 열 기준 각 요일별 팁(tip)의 평균을 새로운 데이터프레임으로 만든 후,
         #이를 기존의 'tips' 데이터셋에 병합

    tip_by_day = tips_data.groupby('day')['tip'].mean().reset_index() #인덱스 추가
    tip_by_day.columns = ['day', 'avg_tips'] #칼럼명 변경 
    tip_by_day 

    merged_df = pd.merge(tips_data, tip_by_day, on = 'day', how = 'inner')
    merged_df

 

 


02. 데이터 시각화(Matplotlib)

1) 데이터 시각화의 목적

① 패턴 발견 및 이해

 : 데이터의 특징을 시각적으로 파악해 데이터 내 숨겨진 패턴을 발견하고, 이해하는 데 도움을 줌 

② 의사 결정 지원
  : 시각화로 정보를 명확하게 전달해 복잡한 데이터를 이해하고 의사 결정을 내리는 데 도움을 줌

③ 효과적인 커뮤니케이션
   : 데이터 분석 결과를 다른 사람들과 공유하거나 설명할 때 유용. 시각적으로 보여주면 이해나 기억이 쉬움

 

(cf) 목적에 맞는 시각화 유형

- 시간에 따른 매출 추이 분석, 마케팅 캠페인 효과 분석: 선 그래프 

- 제품 카테고리별 매출 분석, 캠페인 채널별 효과 비교: 막대 그래프, 원형 차트 

- 고객 구매 패턴 분석, 고객 반응 분석: 히스토그램, 상자 그림(Box Plot)

- 지역별 매출 비교 분석: 지도 이용한 히트맵 

 

 

2) Matplotlib 알아보기

- Matplotlib이란?

 : 파이썬에서 다양한 종류의 그래프 생성에 필요한 도구를 제공하는 시각화를 위한 라이브러리

: 선/막대 그래프, 히스토그램, 산점도, 파이 차트 등 다양한 시각화 방식 지원(주로 2D 그래픽)
: 그래프를 색상, 스타일, 레이블, 축 범위 등을 조절하여 원하는 형태로 시각화 가능

- matplotlib.pyplot : import 라이브러리 이름.

 └ plot() 함수: pyplot 인터페이스에서 2차원 데이터를 시각화하기 위해 사용

 └ matplotlib은 사용 문법이 2종류 하기 내용 참고 
    ① pyplot 인터페이스: 단순한 그래프 또는 임시적인 데이터 시각화에 적합
   ② 객체지향 인터페이스: 복잡한 그래프, 여러 서브플롯, 세밀한 조정이 필요할 때 적합

 

 

3) 그래프 그리기 - 도구

▶ 기본 그래프 그리기 

import pandas as pd
import matplotlib.pyplot as plt

# 샘플 데이터프레임 생성
data = {
    'A': [1, 2, 3, 4, 5],
    'B': [5, 4, 3, 2, 1]
}
df = pd.DataFrame(data)

# 선그래프 그리기
    ax = df.plot(x='A', y='B')

# 그래프 사이즈 설정
    plt.figure(figsize=(8, 6))  # 가로 8인치, 세로 6인치
    #안 먹히면 이걸 넣어야 한다고 함
    fig, ax = plt.subplots(figsize=(8,6)) 

# 범례 추가하기
    ax.legend(['Data Series'])

# 그래프 및 축 이름 설정 
    ax.set_xlabel('X-axis Label')
    ax.set_ylabel('Y-axis Label')
    ax.set_title('Title of the Plot')

# 데이터 레이블 설정 
	ax.text(3, 3, 'Some Text', fontsize=12) #3, 3 위치에 텍스트 삽입 

# 그래프 출력 
    plt.show()

 

▶ 스타일 설정하기 

- color= : 색상값. 'blue', 'green'와 같이 기본 색상 이름을 문자열로 넣거나 RGB 값을 직접 지정도 가능

- Linestyle= :  선 스타일.   '-'(실선), '--'(대시선), ':'(점선), '-.'(점-대시선) 등으로 지정

- marker = : 선 그래프 내 표식. 'o'(원), '^'(삼각형), 's'(사각형), '+'(플러스), 'x'(엑스) 등 다양한 기호로 지정

- label = :  legend 대신 label로 범례 입력 가능 

#예시
    plt.plot(x, y, color='green', linestyle='--', marker='o', label='Data Series')

 

* matplotlib 공식 문서 참조 

- Line API: https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D
- Marker API: https://matplotlib.org/stable/api/markers_api.html
- Line Styles: https://matplotlib.org/stable/gallery/lines_bars_and_markers/line_styles_reference.html

 

 

4) 그래프 그리기 - 차트

▶ 그래프 자료 유형 

그래프 유형 자료 유형 특징
Line Plot 연속형 데이터 데이터의 변화 및 추이를 시각화 (시계열에 따른 추이 확인에 용이)
Bar Plot 범주형 데이터 카테고리(범주) 별 값의 크기를 시각적으로 비교
Histogram  연속형 데이터 데이터 분포, 빈도, 패턴 등을 이해
Pie Chart 범주형 데이터의 비율 범주별 상대적 비율을 부채꼴 모양으로 시각화
Box Plot 연속형 데이터의 분포 중앙값, 사분위수, 최솟값, 최값, 이상치 등 통계적 수치 확인
Scatter Plot 두 변수 간 관계 변수 간의 관계, 군집, 이상치 등 확인 

 

① Line Plot

- 선 그래프는 데이터 간의 연속적인 관계(추이)를 시각화하는 데에 적합. 주로 시간에 흐름에 따른 데이터 변화, 추세 등 

import pandas as pd
import matplotlib.pyplot as plt

# 데이터프레임 생성
data = {'날짜': ['2023-01-01', '2023-01-02', '2023-01-03'],
        '값': [10, 15, 8]}
df = pd.DataFrame(data)

# '날짜'를 날짜 형식으로 변환
df['날짜'] = pd.to_datetime(df['날짜'])

# 선 그래프 작성
plt.plot(df['날짜'], df['값'])
plt.xlabel('날짜')
plt.ylabel('값')
plt.title('선 그래프 예시')
plt.show()

(예시)

 

② Bar Plot vs. Histogram

- 막대 그래프는 각 막대 값의 크기를 통해 범주형 데이터 간(카테고리별) 크기를 비교하는데 효과적

- 히스토그램은 연속형 데이터의 분포를 시각화하여 데이터의 빈도나 분포, 패턴을 이해하는 데 사용

# 막대 그래프 
df = pd.DataFrame(data)

plt.bar(df['도시'], df['인구'])
plt.xlabel('도시')
plt.ylabel('인구')
plt.title('막대 그래프 예시')
plt.show()

# 히스토그램
data = np.random.randn(1000) #랜덤데이터

plt.hist(data, bins=30)
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Histogram')
plt.show()

(예시)

(좌) 막대 그래, (우) 히스토그램

 

③ Pie Chart

- 원 그래프는 전체에서 각 부분의 상대적 비율을 시각화하며, 주로 카테고리별 비율을 비교할 때 사용

import matplotlib.pyplot as plt

# 데이터 생성
sizes = [30, 20, 25, 15, 10]
labels = ['A', 'B', 'C', 'D', 'E']

# 원 그래프 그리기
plt.pie(sizes, labels=labels, autopct='%1.1f%%')
plt.title('Pie Chart')
plt.show()

(예시)

 

 

④ Box Plot

- 박스 플롯은 연속형 데이터의 분포와 이상치를 시각화하고, 중앙값, 사분위수, 최솟/최댓값 등 통계적 특성 파악에 용이 

- 박스 플롯의 활용
 └ 데이터의 분포와 중앙값, 이상치 등 통계적으로 중요한 데이터 특성을 시각적으로 표현할 때 사용
 └ 다수의 그룹 또는 범주 간의 데이터 분포 비교에 유용

- 박스 플롯의 구성 요소 

(1) 상자(Box)

 : 데이터의 중앙값과 사분위수(25%와 75%)를 표현

 : 상자 중앙에 위치한 선 = 중앙값, 상자 아래쪽 끝 = 25%의 값(1사분위수), 상자의 윗쪽 끝 = 75%의 값(3사분위수)

(2) 수염(Whisker)

 : 상자의 위 아래로 연장되는 선으로, 수염의 끝은 최솟값과 최댓값

 : 일반적으로 1.5배의 사분위 범위로 계산하며, 이 범위를 넘어가면 이상치(outlier)로 간주

(3) 이상치(Outliers)

: 일반적인 범위를 벗어나는 값들을 의미

: 수염을 벗어나는 개별 데이터 포인트로 박스 플롯에서 독립적으로 표시

import matplotlib.pyplot as plt
import numpy as np

# 데이터 생성
np.random.seed(10)
data = [np.random.normal(0, std, 100) for std in range(1, 4)]

# 박스 플롯 그리기
plt.boxplot(data)
plt.xlabel('Data')
plt.ylabel('Value')
plt.title('Box Plot')
plt.show()

 

(예시)

 

 

(cf) 간단한 통계 용어 설명 

- 중앙값(Median)
└ 데이터를 크기 순서대로 나열했을 때, 정확히 중간에 위치한 값

  · 홀수일 경우, 작은 것부터 나열한 데이터에서 정확히 가운데에 위치한 값 {3, 6, 7, 12, 14}에서 중앙값은 7

  · 짝수일 경우, 작은 것부터 나열한 데이터에서 가운데 2개의 평균 값  {3, 6, 7, 12, 14, 16} 에서 중앙값은 9.5  

데이터의 중심 경향을 나타내는 하나의 지표로 사용
이상치에 대해 덜 민감하며, 데이터의 대표값을 파악하는 데 사용

 

- 사분위수(quartiles)
데이터를 4등분한 지점으로, 크기 순서대로 정렬했을 때, 25%, 50%, 75%에 해당하는 위치의 값

  · 1사분위수(First Quartile, Q1): 데이터의 하위 25%에 해당하는 값
  · 2사분위수(Second Quartile, Q2): 데이터의 50% 위치로 중앙값(median)에 해당하는 값
  · 3사분위수(Third Quartile, Q3): 데이터의 상위 25%(크기 순으로 75%)에 해당하는 값

└ 데이터의 분포를 더 자세히 이해하고 데이터 집합 특성 파악 및 이상치 감지에 유용

 

- 이상치(outlier)

데이터 집합의 패턴에서 극단적으로 크거나 작은 값을 갖는 데이터 포인트

통계 분석이나 데이터 시각화 과정에서 정확성을 해치거나 모델 성능을 왜곡시킬 수 있어 이상치 식별 및 처리가 중요 

└ Box Plot이나 Histogram 등을 활용해 시각적으로 확인하거나 통계적 방법과 도메인 지식을 활용해 이상지 탐지 및 처리 

이상치는 종종 실수, 실험 오류, 데이터 수집 과정에서 발생한 문제 등으로 인해 나타남

 

⑤ Scatter Plot

- 산점도는 두 변수 간의 관계를 점으로 표시한 그래프로, 점들의 분포를 시각적으로 확인 가능 

- 두 변수 간의 상관 관계를 보여주며, 변수 간의 관계, 군집, 이상치를 확인하고자 할 때 유용

import matplotlib.pyplot as plt

# 데이터 생성
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 7, 11]

# 산점도 그리기
plt.scatter(x, y)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Scatter Plot')
plt.show()

 

▶ 상관관계 

- 해석하기 

 (분포 모양 및 방향)

 └ 양의 상관관계: 오른쪽 위 방향으로 일직선 분포. 한 변수가 증가하면 다른 변수도 증가하는 경향성을 보임
 └ 음의 상관관계: 왼쪽 위 방향으로 일직선 분포. 한 변수가 증가하면 다른 변수는 감소하는 경향성을 보임
 └ 무상관 관계: 점이 경향성 없이 무작위로 퍼져 있는 분포. 두 변수 간에는 상관관계가 거의 없는 것으로 봄

 (분포 강도 )
 └  점들의 모임: 점들이 더 밀집된 곳은 상관관계가 강할 가능성이 높음
 └  점들의 방향성: 일직선에 가까운 분포일수록 상관관계가 강할 가능성이 높음
 └  상관계수 계산: 피어슨 상관계수와 같은 통계적 방법을 사용하여 상관관계를 수치적으로 계산 가능

 

▶ 피어슨 상관계수(Pearson correlation coefficient)란?
- 두 변수 간의 선형적인 관계를 측정하기 위한 통계적인 방법 중 하나

- 주로 연속형 변수들 간의 상관관계를 평가하는 데 사용

 


- 피어슨 상관계수의 특징
└ 범위: -1에서 1 사이의 값
└ 양의 상관관계: 1에 가까울수록 강한 양의 선형관계. A가 증가하면 B도 증가 
└ 음의 상관관계: -1에 가까울수록 강한 음의 선형관계. A가 증가하면 B는 감소
└ 무상관 관계: 0에 가까울수록 선형관계가 거의 없거나 약한 관계

└ 피어슨 상관계수는 공분산을 각 변수의 표준편차로 나누어 정규화한 값으로, 두 변수 간의 선형적 관계 정도를 측정

└ 변수 간의 비선형적 관계는 표현이 어려울 수 있고, 이상치에도 영향을 받음

[!] 상관이 있다고 해서 인과 관계가 있는 것은 아님. A가 증가하면 B가 증가하는 것이 A 때문은 아님. 

 

(cf) 간단한 통계 용어 설명

 

- 표준편차(standard deviation)

데이터의 분산 정도를 나타내는 측정 지표 중 하나로 데이터가 평균으로부터 얼마나 퍼져 있는지를 보여줌

표준편차가 작을수록 각 데이터가 평균 주변에 모여있고, 표준편차가 클수록 각 데이터가 평균에서 멀리 퍼져있음
- 공분산(covariance)

└ 두 변수의 변화 패턴이 함께 일어나는 정도를 측정하는 통계적 측정 지표

 공분산이 양수면 변수X와Y는 함께 증가 또는 감소하는 경향이 있고, 음수면 한 변수가 증가 시 다른 변수는 감소 경향

공분산 값 자체만으로는 두 변수 간의 관계의 강도나 방향은 알기 어려워, 상관계수를 활용해 관계를 명확히 파악
- 정규화(normalization)

데이터의 스케일(scale)을 조정하여 특정 범위나 규격에 맞추는 과정
  정규화의 장점

   · 데이터 스케일 조정: 서로 다른 범위에 있는 데이터를 특정 범위로 조정해 알고리즘의 데이터 처리를 도움 

   ·  이상치 영향 완화: 정규화를 통해 이상치의 영향 감소  

   · 알고리즘의 수렴성 향상: 몇몇 머신 러닝 알고리즘은 데이터가 정규화되어 있을 때 수렴 속도 개선