[KT 에이블스쿨 5기] DX트랙 2주 4일차 복습_넘파이 기초, 판다스 데이터 프레임 생성 및 탐색
**셀프 복습용으로 작성한 것이라 실수가 있을 수 있습니다!
혹시 실수를 발견하시면 댓글로 알려주시면 감사드리겠습니다 :)
01 넘파이 기초
Numpy 배열의 기본 개념을 이해하기!
1-3차원 배열을 만들 수 있음
Reshape 기능을 사용해 배열의 형태를 바꿀 수 있음
인덱싱과 슬라이싱으로 원하는 데이터를 조회
배열 사이의 기본적인 연산을 수행 가능
라이브러리 불러오기
- Numpy 배열을 사용하려면 numpy 라이브러리 불러오기 → 일반적으로 np 별칭을 붙여 불러옴
# 라이브러리 불러오기
import numpy as np # np.????()형식으로 활용할 수 있음
- 배열을 출력하려면 → print함수를 꼭 사용하자!
배열 만들기
- 편의를 위해 Numpy 배열을 그냥 배열이라고 부름
- 이후 데이터 처리 시 배열로 변환해 연산을 하거나, 결과가 배열로 표시되는 경우가 있음
- np.array() 함수를 사용해서 배열을 만듦
- 대부분 리스트로부터 배열을 만들거나, 머신러닝 관련 함수 결괏값이 배열됨
- 배열은 자료형을 한 개만 가질 수 있다 (숫자면 숫자만, 문자면 문자만!)
- 용어
- axis: 배열의 각 축 (axis 0: 행, axis 1:열)
- rank: 축의 개수
- shape: 축의 길이, 배열의 크기
- [3 x 4 배열의 경우]
- axis 0 과 axis 1 을 갖는 2차원 배열
- rank 2 array
- shape는 (3, 4); 튜플 형태
배열 만들기
1) 1차원 배열 만들기
a1 = [1, 2, 3, 4, 5] # 1차원 리스트
b1 = np.array(a1) # 배열로 변환
print(b1) # axis 0밖에 없음 [ 1 2 3 4 5 ]
2) 2차원 배열 만들기
# 2차원 리스트
# a2 = [[1.5, 2.5, 3.2], [4.2, 5.7, 6.4]]
a2 = [[1.5, 2.5, 3.2],
[4.2, 5.7, 6.4]]
b2 = np.array(a2) # 배열로 변환
print(b2) # 확인 [[1.5, 2.5, 3.2]
[4.2, 5.7, 6.4]]
3) 3차원 배열 만들기 → 3차원일 때는 2차원과 2차원 사이의 깊이가 axis0, 행이 axis1, 열이 axis2
# 3차원 리스트
# a3 = [[[1, 3, 1], [4, 7, 6], [8, 3, 4]], [[6, 2, 4], [8, 1, 5], [3, 5, 9]]]
a3 = [[[1, 3, 1],
[4, 7, 6],
[8, 3, 4]],
[[6, 2, 4],
[8, 1, 5],
[3, 5, 9]]]
b3 = np.array(a3) # 배열로 변환
# 확인
print(b3) #[[[1 3 1]
[4 7 6]
[8 3 4]]
[[6 2 4]
[8 1 5]
[3 5 9]]]
- (2, 3, 3) : 3 X 3의 2차원 배열이 2개 겹쳐있다는 뜻!
배열 정보 확인
- 배열 정보를 확인하는 속성 기억
1) 차원 확인: ndim 속성으로 괄호 사용 X
2) 형태(크기) 확인: shape 속성으로 배열 형태 확인
3) 요소 자료형 확인: dtype 속성으로 배열에 포함된 요소들의 자료형 확인 → 배열은 한 가지 자료형만 가짐
Reshape
- 배열을 사용할 때 다양한 형태(shape)로 변환할 필요가 있음
- 배열에 포함된 요소가 사라지지 않는 형태라면 자유롭게 변환
- (3, 2) → (2, 3) → (1, 6) → (6, 1) 등 요소 개수만 변하지 않으면 됨!
- a.reshape(행, 열) 형태로 작성
- -1의 편리성: **(m, -1) 또는 (-1, n)**처럼 사용하며 행 또는 열 크기 한 쪽만 지정할 수 있음!
배열 인덱싱과 슬라이싱
- 지금까지 다룬 자료형들보다 배열 인덱싱과 슬라이싱이 난이도 조금 높음
인덱싱
- 1차원 배열은 리스트와 방법이 같음
- 배열[행, 열] 형태로 특정 위치의 요소를 조회
- 배열[[행1, 행2],…:] 또는 배열[[행1, 행2,..]] 형태로 특정 행을 조회
- 배열[:, [열1, 열2,…]] 형태로 특정 열을 조회
- 배열[[행1, 행2, …], [열1, 열2,…]] 형태로 특정 행의 특정 열을 조회
1) 요소 조회
# (3, 3) 형태의 2차원 배열 만들기
a = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(a[0, 1]) # 첫 번째 행, 두 번째 열 조회
2) 행 조회
# 첫 번째, 두 번째 행의 모든 열 조회
# print(a[[0, 1], :])
print(a[[0, 1], :]) #뒤에 오는 콜론은 생략 가능 (앞에 오는 콜론은 생략 불가)
3) 열 조회
# 첫 번째, 두 번째 열 조회
print(a[:, [0, 1]])
4) 행, 열 조회
#두 번째 행 두 번쨰 열의 요소 조회
print(a[[1], [1]])
# 세 번째 행 두 번째 열의 요소 조회
print(a[[2], [1]])
# 첫 번째 행 첫 번째 열, 두 번째 행 두 번째 열의 요소 조회
print(a[[0, 1], [0, 1]])
# 첫 번째 행 첫 번째 열, 두 번째 행 두 번째 열, 세 번째 행 첫 번째 열의 요소 조회
print(a[[0, 1, 2], [0, 1, 0]])
슬라이싱
- 배열[행1:행N, 열1:열N] 형태로 지정해 그 위치의 요소를 조회
- 조회 결과 2차원 배열
- 마지막 범위 값은 대상에 포함되지 X
- 배열[1:M, 2:N] 이라면 1 M-1행, 2 ~N-1열이 조회 대상이 됨
조건 조회
- 조건에 맞는 요소를 선택하는 방식, 불리안 방식이라고 불름
- 조회 결과는 1차원 배열이 됨
# 2차원 배열 만들기
score= np.array([[78, 91, 84, 89, 93, 65],
[82, 87, 96, 79, 91, 73]])
# 확인
print(score)
- 배열[조건] 형태로 해당 조건에 맞는 요소만 조회
- 검색 조건을 변수로 선언해 사용할 수 있음
# 요소 중에서 90 이상인 것만 조회
print(score[ score >= 90 ] )
# 요소 중에서 90 이상인 것만 조회
cond = score >= 90
print(score[ cond ])
- 검색 조건을 변수로 선언해 사용할 수도 있음
# 요소 중에서 90 이상인 것만 조회
cond = score >= 90
print(score[ cond ])
- 여러 조건을 &와 |로 연결하여 조회 가능
# 모든 요소 중에서 90 이상 95 미만인 것만 조회
print(score[(score>= 90) & (score < 95)])
print(score[(90 <= score < 95)]) #넘파이 지원 안 함으로 오류
배열 연산
- 배열 사이의 더하기, 빼기, 곱하기, 나누기 등은 이해하기 쉬움
- 하지만 행렬 곱, 행렬 합등의 연산은 약간의 수학적 지식 필요
- 행렬 연산은 선형 대수를 위한 것이므로 설명 생략
1) 배열 더하기
- + 또는 np.add()함수 사용
print(x + y) # 배열 더하기
print(np.add(x, y)) # 또는
2) 배열 빼기
- - 또는 np.subtract()함수 사용
print(x - y) # 배열 빼기
print(np.subtract(x, y)) # 또는
3) 배열 곱하기
- *또는 np.multiply()함수 사용
print(x * y) # 배열 곱하기
print(np.multiply(x, y)) # 또는
4) 배열 나누기
- / 또는 np.divide()함수 사용
print(x / y) # 배열 나누기
print(np.divide(x, y)) # 또는
5) 배열 제곱
- ** 또는 np.power()함수 사용
print(x ** y) # 배열 y 제곱
print(np.power(x, y)) # 또는
# 배열 제곱
print(x ** 2)
02 판다스 데이터프레임 생성
데이터프레임 이해
Pandas 사용 목적이 = 데이터프레임을 사용하기 위한 목적
데이터를 처리, 조회, 분석하는 가장 효율적인 방법이 데이터프레임을 사용하는 것
일반적으로 접하게 되는 테이블 형태, 엑셀 형태로 생각
직접 만들 수 있으나 보통은 csv 파일, 엑셀 파일 또는 DB에서 읽어옴
데이터프레임 형태
데이터프레임은 인덱스(=행 이름)와 열 이름이 있고 없고에 따라 다른 형태를 가짐
인덱스란 행을 특정지어 조회할 때, 열 이름은 열을 특정지어 조회할 때 사용하는 정보
1) 인덱스와 열 이름이 없는 형태
0 | 1 | 2 | |
0 | 2024-03-02 | 94500 | 65000 |
1 | 2024-03-03 | 95500 | 77000 |
2 | 2024-03-04 | 85000 | 65000 |
2) 열 이름을 지정한 형태
- 열 이름만 지정한 데이터프레임 형태
- 특별히 인덱스를 지정할 필요가 없는 경우가 많으므로 자주 보게 되는 형태
Date | High | Low | |
0 | 2024-03-02 | 94500 | 65000 |
1 | 2024-03-03 | 95500 | 77000 |
2 | 2024-03-04 | 85000 | 65000 |
3) 인덱스와 열 이름을 지정한 형태
- 인덱스와 열 이름 모두 지정한 데이터프레임 형태
- 주식 시세와 같이 날짜가 인덱스로 지정되는 경우가 많음
High | Low | |
2024-03-02 | 94500 | 65000 |
2024-03-03 | 95500 | 77000 |
2024-03-04 | 85000 | 65000 |
데이터프레임 직접 만들기
pd.DataFrame()함수를 사용해 데이터프레임 직접 만들 수 있음
대부분 리스트, 딕셔너리, Numpy 배열로부터 데이터프레임을 만듦
데이터프레임을 만들기 위해서 세 가지를 위한 데이터가 필요! (데이터, 열 이름, 인덱스 이름)
열 이름을 지정하지 않으면 열 번호에 기반한 정수 (0, 1, 2...)가 열 이름이 됨
인덱스 이름을 지정하지 않으면 행 번호에 기반한 정수 (0, 1, 2..)가 인덱스 이름이 됨
머신러닝 모델의 성능 정보 등을 데이터프레임 형태로 분석해야 할 경우가 있음
라이브러리 불러오기 (리스트, 딕셔너리로 만들기)
- 데이터프레임을 사용하기 위해서 pandas 라이브러리를 pd별칭을 주어 불러옴!
- 인덱스를 지정하지 않으면 행 번호가 인덱스, 열 번호가 열 이름이 됨
import pandas as pd
import numpy as np
#1차원 리스트 만들기
stock = [94500, 92100, 92200, 92300]
# 데이터프레임 만들기
df = pd.DataFrame(stock)
df.head()
#괄호 안에 숫자를 작성하지 않으면 → 전부 출력(5개 이상이면 위에서부터 5개만 출력)
#숫자 입력 → 숫자만큼 출력
- 필요하면 인덱스와 열 이름을 별도로 지정 가능!
- .tail(): 끝에서부터 출력, .plot()은 그래프로 시각화
# 리스트 만들기
stock = [[94500, 92100, 92200, 92300],
[96500, 93200, 95900, 94300],
[93400, 91900, 93400, 92100],
[94200, 92100, 94100, 92400],
[94500, 92500, 94300, 92600]]
dates = ['2019-02-15', '2019-02-16', '2019-02-17', '2019-02-18', '2019-02-19']
names = ['High', 'Low', 'Open', 'Close']
# 데이터프레임 만들기
df = pd.DataFrame(stock, index=dates, columns=names) #데이터, 인덱스, 컬럼 순
df.head()
- 딕셔너리로 데이터프레임을 만들면 딕셔너리의 키가 열 이름이 됨!
- 인덱스를 지정하지 않으면 행 번호가 인덱스가 됨!
# 딕셔너리 만들기= {'Name': ['Gildong', 'Sarang', 'Jiemae', 'Yeoin'],
'Level': ['Gold', 'Bronze', 'Silver', 'Gold'],
'Score': [56000, 23000, 44000, 52000]}
df = pd.DataFrame(mem)
df.head()
- 필요하면 인덱스 별도로 지정 가능! df = pd.DataFrame(mem, index=['m1', 'm2', 'm3', 'm4'])
CSV파일 읽어오기
분석용 데이터는 대부분 파일에서 읽어옴!
read_csv()함수를 사용해 CSV 파일에서 데이터를 읽어옴!
[주요옵션]
sep: 구분자 지정(기본값 = 콤마)
header: 헤더가 될 행 번호 지정(기본값 = 0)
index_col: 인덱스 열 지정(기본값 = False)
names: 열 이름으로 사용할 문자열 리스트
encoding: 인코딩 방식을 지정
※ 참고
한글이 포함된 파일을 읽을 때 다음과 같은 encoding 오류가 발생하면 encoding='CP949'로 지정
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 0: invalid start byte
# 데이터 읽어오기
path = '경로링크 복사붙여넣기'
pop = pd.read_csv(path)
# 상위 10행만 확인
pop.head(10)
인덱스 다시 설정
일반 열을 인덱스 열로 설정하거나, 행 순서에 기반한 정수값 인덱스로 초기화할 수 있음
1) 일반 열을 인덱스로 지정
파일을 불러올 때 index_col 옵션을 사용해 인덱스가 될 열을 선택할 수 있음!
파일을 불러온 후에 set_index() 메서드를 사용해 인덱스가 될 열을 설정할 수 있음!
# 기존 열 중 하나를 인덱스로 설정
# pop = pop.set_index('year') → set.index()는 반환하고 있기 때문에 변수에 반환해야 인덱스 설정 가능
pop.set_index('year', inplace=True) #위와 동일함
2) 인덱스 이름 삭제
- 인덱스 이름은 특별히 사용할 일이 없으므로 pop.index.name = None 사용해 삭제
3) 인덱스 초기화
- reset_index() 메서드를 사용해 행 번호에 기반한 정수 값으로 인덱스를 초기화할 수 있음 pop.reset_index(drop=False, inplace=True)
- drop = True를 설정하면 기존 인덱스 열을 일반 열로 가져오지 않고 버림 (기본값 = False)
- 기존 인덱스를 제거하지 않으면 'index'라는 이름의 열이 되니 적절하게 열 이름을 변경!
pop.rename(columns={'index':'year'}, inplace=True)
03 판다스 데이터프레임 탐색
데이터프레임 탐색은 데이터프레임의 키와 몸무게를 재는 것
파일에서 불러온 데이터의 크기, 내용, 분포, 누락된 값 등을 확인
확인된 내용을 통해 데이터 전처리 필요 여부를 결정 → 데이터를 알아야 데이터를 분석할 수 있음!
앞, 뒤 일부 데이터, 크기 확인
1) head(n): 상위 데이터 확인
2) tail(n): 하위 데이터 확인
- 개수를 지정하지 않으면 기본적으로 5개의 행을 조회
3) shape: 값을 갖는 튜플 (rows, cols) 형태로 확인 가능, 행 수와 열 수 확인
- 데이터를 분석할 때 처리하는 데이터 양을 확인하는 목적
- shape[0], len(자료명): 행 수 알 수 있음, shape[1] 열 수 알 수 있음
열, 행 정보 보기
1) index: 인덱스 확인
2) values: 값 확인, 속성 조회 결과는 Array(배열)
3) columns: 열 확인
4) dtypes: 열 자료형 확인
5) info(): 열 자료형, 값 개수 확인
6) describe(): 기술 통계 확인, 데이터의 정리, 요약, 해석, 표현 등을 통해 데이터가 갖는 특성을 나타내는 정보
- 개수(count), 평균(mean), 표준편차(std), 최솟값(min), 사분위값(25%, 50%, 75%), 최댓값(max)을 표시
- 아래처럼 일부 열에 대해서만 기술 통계 확인도 가능
# 기술 통계
tip[ ['tip', 'total_bill'] ].describe().T #.T는 행열 바꿈
정렬해서 보기
인덱스를 기준으로 정렬하는 방법과 특정 열을 기준으로 정렬하는 방법이 있음
sort_values() 메서드로 특정 열을 기준으로 정렬함
ascending 옵션을 설정해 오름차순, 내림차순 설정
- ascending = True: 오름차순 정렬 (기본값)
- ascending = False: 내림차순 정렬
# 단일 열 정렬 → tip에 반영이 된 것은 아님!
tip.sort_values(by = 'total_bill', ascending=False)
# 복합 열('total_bill', 'tip') 정렬
tip.sort_values(by = ['total_bill', 'tip'], ascending=[False,True]).head()
기본 집계
고유값 확인
범주형 열(열이 가진 값이 일정한 값인 경우, 성별, 등급 등)인지 확인할 때 사용
1) unique(): 고윳값을 확인하며, 결괏값은 배열 형태가 됨!2) value_counts(): 고윳값과 개수 확인, 결괏값은 시리즈 형태가 됨- dropna 옵션을 생략하거나 dropna = True로 지정하면 NaN 값은 대상에서 제외
tip['day'].unique() # day 열 고윳값 확인
tip['day'].value_counts() # day 열 고윳값 개수 확인
3) smoker 열 고윳값 비율 확인
tip['smoker'].value_counts(normalize=True)*100
tip['smoker'].value_counts() / len(tip) *100
최빈값 확인
mode() 메서드
최빈값은 가장 많이 관측되는 수 = 주어진 값 중에서 가장 자주 나오는 값
ex) {1, 3, 6, 6, 6, 7, 7, 12, 12, 17}의 최빈값은 6입니다.
최빈값은 산술 평균과 달리 유일한 값이 아닐 수도 있음!
최빈값이 여렷인 경우 행으로 구분되어 표시
기본 통계 메서드 사용
df.sum()은 df.sum(axis=0) 과 같으며 전체 열 기준으로 합을 집계
전체 행 기준으로 집계를 하려면 df.sum(axis=1) 형태로 axis=1을 지정
위를 활용해 열 합계 sum(axis=0), 열 최댓값 man(axis=0), 열 평균 값은 mean(axis=0), 열 중앙값은 median(axis=0)으로 활용