- 주어진 데이터 수집/ 가공/변형/결과 : 파이썬
- 기본적인 파이썬 문법
- 파이썬 계열의 데이터 처리 패키지
- pandas →DF
- 하지만 근본은 numpy: array
numpy
: 데이터를 처리하는 과정에서 가장 기본이 되는 패키지
numerical python
- 수치 연산
- 쌩파이썬의 자료형으로 연산/ 벡터 산수가 불편함 ⇒ 모든 원소에 일괄 적용 “벡터 연산” 자료형 ⇒ 수식상 표현을 그대로 코드화 가능
pandas/ scikit-learn / TF/ PyTorch 에서 가장 기본이 되는 자료형
anaconda로 설치하면 → numpy, pandas 기본 설치 되어 있는 패키지 → 불러다가 사용만 하면 됨
colab에서는 이미 설치가 되어있음 단, colab은 자기가 버전 수정을 해야함 (업그레이드는 원하지 않아도 함) 이래서 중간에 코드가 되다가 밥 먹고 오면 안 되는 경우도 있음 이제는 많이 안정회 되긴 함
import numpy as np
import pandas as pd
# 지금 내가 사용하는 패키지의 버전!!!!
pd.__version__ # 언더바 2개 앞뒤로
#2.2.2
np.__version__
#2.0.2
# --> 오늘 기준으로 2.3.0인데,,약간 올드 버전 사용함!!!
# 이유 : 다른 패키지에 연동이 되고,,1과 2가 많이 달라서 호환성이 문제가
# pytorch 하고,,,,
numpy를 만들게 된 이유
- 수치 연산을 파이썬에서 하자
- 기존의 파이썬 자료형
- 리스트, 튜플, dict etc… ⇒ 수치 연산에 특화되지 않음
- 수치 연산 적당한 자료형 제안→ numpy 만들게 됨
- 벡터 연산
- 개별 원소 중심이 아니라, 기능/액션 중심의 표현
- 기능 중심의 코드화
- 태생이 파이썬 → 상당히 느린 경향이 있지만 대신 편하게 코드화됨
- 실제 개발/시스템 → 다른 언어로 같이 사용하는 경우 있음
쌩 파이썬
- 리스트 → 값을 모아두자 → 벡터와 유사함
- 2차원 좌표 평면 : 차원은 없지만 오/열 맞춰서 차원을 유사 표현
- ⇒ 모든 값에 일괄 적용 : 벡터 연산의 기능이 없음 모든 값을 롤링 : for → LC
- ex) x = [1,2,3] 모든 원소에 +100을 하자
- ⇒ [1+100, 2+100, 3+100]
- 규칙 : 벡터로 표현 x + 100
a = [ 100,200,300,400,500] a #[100, 200, 300, 400, 500] # 쌩 파이썬의 리스트+ 5개 원소 ==> 모든 원소에 +10을 하자!!!!! # m1) 그냥 돌리기 : 값 자체 vs 정수인덱스 b = [] for i in a: b.append( i + 10) b #[110, 210, 310, 410, 510] # m2) LC [i+10 for i in a] #[110, 210, 310, 410, 510] a + 10 # ==> 이렇게 수식적인 벡터 표현을 그대로 코드화 되면 좋을 텐데... #오류남 # m3) numnpy의 array 자료형 --> 내부에 벡터연산이 되도록 만든 새로운 자료형!!! # ==> 외부 개발잘/커뮤니티 중심으로 만들어서 배포/유지 보수.. a_arr = np.array( a ) a_arr #array([100, 200, 300, 400, 500]) b = [] for i in a_arr: b.append(i+10) b #[np.int64(110), np.int64(210), np.int64(310), np.int64(410), np.int64(510)] a_arr + 10 #array([110, 210, 310, 410, 510])
- 벡터연산이 기본적으로 "기능 중심의 표현"
- 코드 작성 "기능 중삼"으로 코드 작성이 용이하게 되고
- +파이썬과 손발이 잘 맞게 되었고
- +비전공 영역에서 파이썬 기반의 데이터 핸들링이 확 퍼지게 되었다.
- --> numpy ---> pandas
# ex)
x = [ 1,2,3,4,5]
y = [10,20,30,40,50]
# --> ( 1+10, 2+20, 3+30, 4+40, 5+50)
# 수학적인 벡터라 생각하면 : x+ y
# m1) 쌩파이썬
z = []
for i in range(len(a)):
# 임의의 i번째 원소를 가지고,,,뭘 할지
z.append( x[i] + y[i])
z
#[11, 22, 33, 44, 55]
# m2) 쌩파이썬 ---> LC
[ x[i] + y[i] for i in range(len(a)) ]
#[11, 22, 33, 44, 55]
# m3) numpy의 array 자료형으로 변경!!!
x_arr = np.array( x)
y_arr = np.array(y)
x_arr
#array([1, 2, 3, 4, 5])
y_arr
#array([10, 20, 30, 40, 50])
x_arr + y_arr
#array([11, 22, 33, 44, 55])
그래서 이 내용이 나랑 무슨 상관인가?
- 앞으로 데이터 핸들링 하는 과정에서도 고려할 요소가 개별 원소값이 기준이 아니라 줄 단위(row, col)으로 무엇을 할지 **“기능 중심”**으로 생각하고, → 그걸 그대로 코드화 함
차원에 대한 내용을 추가적으로 다루고 있음
- 쌩 파이썬의 리스트
- 값들을 모아두자
- 값 → 숫자, 문자, 리스트 … ect
- 차원에 대한 정보는 없음
- 일괄적용도 없음
m=[ [1,2,3], [5,6,7] ] m[가로줄][세로줄] - numpy의 array
- 값들을 모아두는 것
- 값 → 숫자, 문자, 리스트 etc…
- 차원에 대한 정보를 생성 (오/열/값 종류) → 차원으로 인식함
- 기능(벡터 연산은 기본)
a = [ 1,2,3,"a", ["a","b","c",[1,2,3]]] a #[1, 2, 3, 'a', ['a', 'b', 'c', [1, 2, 3]]] np.array(a) #오류남 np.array( [1,2,3,["a","b"]]) #오류남 #이렇게까지 복잡한 건 안 해줌 np.array( [1,2,3,"a","b"]) #array(['1', '2', '3', 'a', 'b'], dtype='<U21') # --> 현실적으로 이렇게 쓸 일이 없어요!!!! #적당한 수준으로는 해준다 test_arr = np.array( [ 1,2,3,4,5]) test_arr #array([1, 2, 3, 4, 5]) test_arr.dtype #dtype('int64') test_arr + 1 #array([2, 3, 4, 5, 6]) test_arr * 10 #array([10, 20, 30, 40, 50]) test_arr.ndim #1 test_arr.shape #(5,) # cf) 2차원 평면/ 행렬 test = [ [1,2,3], [4,5,6] ] test #[[1, 2, 3], [4, 5, 6]] test_arr = np.array( test) test_arr #array([[1, 2, 3], # [4, 5, 6]]) test_arr.ndim #2 test_arr.shape #(2, 3) len(test_arr) #2 # --> 2차원의 자료형이지만,,, # 파이썬의 입장에서 큰 틀 기준 : 2개 원소,,,,, # 2차원 행렬에서는 가로줄 수 # --> len(df) : 2차원 가로줄 수 == 데이터 수 test_arr.shape[0] #2 # 참고) test 라는 리스트 기반의 1번 가로줄, 2번 세로줄 값 : 2 # ==> 접근 방식... test[0][1] #2 test_arr[0][1] #np.int64(2) test_arr[ 0, 1] # -->차원에 대한 양식 --> 가로/세로 인덱스기반으로 바로 접근!! #np.int64(2) test[0,1] # 쌩파이썬은 불가능!!! --> 순차적으로 하나씩 접근만 가능!!! #오류남 # 리스트 --> 값에 대한 접근 : 정수인덱스!!! # --> 여러개 & 규칙 : 슬라이싱!!! a = [10,20,30,40,50] a_arr = np.array(a) a[:3] #[10, 20, 30] a_arr[:3] #array([10, 20, 30]) a[::2] #[10, 30, 50] a_arr[::2] #array([10, 30, 50]) # 참고) a의 원소중에서 0,1,3번째 원소만 보자... a[ [0,1,3]] #오류남 a_arr[ [0,1,3]] #array([10, 20, 40]) # --> 인덱스 자리에 내가 보고자 하는 것들을 리스트업!! # 알아서 그것들만 보여준다!! 필터링!!!!
ref : https://numpy.org/doc/stable/reference/arrays.dtypes.html
- numpy가 수치연산이 일단 제일 큰 목적 : 여러가지 수치형 자료 유형을 만들어 둠
- float 16, 32, 64, …etc
b = [1,2,3]
b_arr = np.array(b)
b_arr
#array([1, 2, 3])
b_arr.dtype
#dtype('int64')
b_arr = np.array(b, dtype=np.float32)
b_arr # --> dtype : 넘파이가 만들어둔 자료형으로 변환을 요청!
#array([1., 2., 3.], dtype=float32)
b_arr.astype(np.int32)
#array([1, 2, 3], dtype=int32)
str(1) #'1'
int("1") #1
# ==> 파이썬에서 했던 대로
# 자료형에 대한 변경 왔다 갔다 할 수 잇음
# --> astype() 공식적인 기능/ 메서드 통해서 상호 변환
넘파이의 array에서 인덱스 연습

m = [
[0,1,2,3,4,5],
[10,11,12,13,14,15],
[20,21,22,23,24,25],
[30,31,32,33,34,35],
[40,41,42,43,44,45],
[50,51,52,53,54,55]
]
m
list(range(0,6,1)) #벡터연산 안 됨
#[0, 1, 2, 3, 4, 5]
np.arange(0,6,1) # 벡터연산 가능
#array([0, 1, 2, 3, 4, 5])
np.arange(0,51,10)[:,np.newaxis]
#array([[ 0],
# [10],
# [20],
# [30],
# [40],
# [50]])
# 1차원에 축을 추가해서 2차원으로 확장하는 것
#보통 이렇게 .newaxis 활용해 직접 만들어서 할 일은 거의 없지만 알아둬
np.arange(0,51,10)[:,np.newaxis] + np.arange(0,6,1)
#array([[ 0, 1, 2, 3, 4, 5],
# [10, 11, 12, 13, 14, 15],
# [20, 21, 22, 23, 24, 25],
# [30, 31, 32, 33, 34, 35],
# [40, 41, 42, 43, 44, 45],
# [50, 51, 52, 53, 54, 55]])
a=np.arange(0,51,10)[:,np.newaxis] + np.arange(0,6,1)
a
#array([[ 0, 1, 2, 3, 4, 5],
# [10, 11, 12, 13, 14, 15],
# [20, 21, 22, 23, 24, 25],
# [30, 31, 32, 33, 34, 35],
# [40, 41, 42, 43, 44, 45],
# [50, 51, 52, 53, 54, 55]])
type(a)
#numpy.ndarray
a.ndim
#2
a.shape
#(6, 6)
a.dtype
#dtype('int64')
- 목적 : 2차원에서 우너하는 값에 대한 접근을 해보자
- 기준 생파이썬 리스트의 관점: 순차적으로 접근 -> 어느 가로줄-->어느 세로줄
- 2차원 numpy의 array접근
-
- 쌩 파이썬 입장
- 가로 접근 후 → 원하는 세로 접근
- a[가로][세로]
-
- +++원하는 위치에 대한 좌표로 한 번에 접근
- a[가로, 세로]
-
a[1][1]
#np.int64(11)
a[ 1,1 ]
#np.int64(11)
# Q) 주황색
a[0][3:5]
#array([3, 4])
a[ 0, 3:5]
#array([3, 4])
#Q) 세로 빨간 줄: 가로줄 --> 모든 가로줄, 세로줄 --> 2번째 줄
a[:,2]
#array([ 2, 12, 22, 32, 42, 52])
#Q) 초록색 덩어리
# ==> 가로: 규칙 존재 & 여러개 -> 2번째 가로줄 부터 끝까지 퐁당퐁당
# 세로: 규칙 존재 & 여러개 -> 0번째 세로줄 부터 끝까지 퐁당퐁당
a[2::2, ::2]
#array([[20, 22, 24],
# [40, 42, 44]])
#Q) 우측 하단
# ==> 가로 ; 4번째 줄 부터~~~
# 세로 : 4번째 줄 부터~~~
a[4:, 4:]
#array([[44, 45],
# [54, 55]])
불리언 인덱싱
- 인덱스
- 정수, 슬라이싱 (쌩 파이썬 리스트도 다 가능)
- 가로/세로 위치(들)
- 여기에 +++ 조건식을 넣으려고함 ⇒ 이게 불러언 인덱싱
- 불리언 인덱싱
- numpy의 array 자료형 인덱스 [ ] 안에 “조건식”이 들어갈 수 있음
- 의미
- 조건식에 대한 데이터 필터링
- sql) where, having ~~ etc
- pandas) 데이터 필터링을 할 때 : 인덱스 자리에 조건식
- 왜 가능할까?
- 벡터연산 ! ⇒ 모든 원소에 일괄 적용
test_arr = np.arange(1,11,1)
test_arr
#array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
#ex) 5보다 작은 값들만 추리고 싶다
# sql : ~~where a<5 etc
# 쌩파이썬 : LC + (for + if)
test_arr + 5
#array([ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
test_arr < 5
#array([ True, True, True, True, False, False, False, False, False, False])
test_arr[test_arr < 5]
#array([1, 2, 3, 4])
# *** 인덱스 자리에 조건식이 들어가게 됨
# 모든 원소에 해당 조건식이 만족하는지 체크
# Y/N(True/False) 논리값 불리언값
# ==> array의 인덱스 자리에 들어가면 True에 해당하는 값만 보여줌
# *** 원하는 조건에 대한 필터링 ***
참고) numpy 수식 연산 패키지
- 산수 연산에 특화가 되어 있습니다..여러 수식 함수들이 있음.!!!
- 메뉴얼. gpt 이용해서 필요한 거 검색해서 가져다 사용하시면 된다.
test_arr
#array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
sum(test_arr) # --> 파이썬의 sum 함수를 활용해서 진행!!!!
#np.int64(55)
test_arr.sum()
#np.int64(55)
# --> numpy가 미리 만들어둔 sum 함수/메서드를 사용해서 구해줘
#더 큰 데이터에서는 좀 더 효율적
numpy 핵심
-
- 기능 : 여러개의 값을 모아둠, 오/열 맞춰서 + 형식까지 맞춰서
-
- 연산
- 모든 원소에 일괄 적용 벡터연산을 기본 + 차원
- 내가 직접 개별 원소 롤링 안 해도 됨 → 기능 중심 코드
-
- 값에 대한 접근
- 순차적으로 접근 (리스트) vs 직접 접근
- array[정수]
- array[슬라이싱]
- array[리스트] : 2D 이상에서는 좀 주의해야함
- ****array[조건식] : 불리언 인덱싱 ⇒ 필터링
- ++2D array : 가로/세로 각기 독립적으로 접근
- array[가로, 세로]
- array[가로정수, 세로정수]
- array[가로슬라이싱, 세로슬라이싱]
- array[가로정수, 세로 슬라이싱] ** 혼합도 가능
- array[가로 조건식, 세로 조건식] : 원하는 가로/세로 필터링 가능
- 참고 ) 속성
- arr.ndim
- arr.shape
- arr.dtype