[아이티윌 빅데이터 52기] Data Analysis Basic | Lab 01 | NumPy Library
[아이티윌 빅데이터 52기] Data Analysis Basic | Lab 01 | NumPy Library
*모든 자료의 저작권은 아이티윌 이광호 강사님
<학습 내용>
- NumPy 시작하기
-ndarray 의 주요 기능
-그 밖의 ndarray 형태
-ndarray 형태 변환
1. NumPy 시작하기
NumPy 는 파이썬으로 할 수있는 수치 계산도구
C 를 파이썬으로 감싸고 있기 때문에 속도 처리가 빠름
가장 중요한 점은 리스트의 단점을 보완하고 있다는 점 (효율성)

NumPy 의 핵심 자료 구조는 ndarray
ndarray 는 리스트 처럼 생긴 배열, 일반 리스트와의 차이는 규칙적인 데이터들의 묶음
리스트는 데이터 타입에 제약이 없지만 배열은 같은 타입만 넣을 수 있음
n 차원의 객체로 평균 행렬 연산 등을 한번에 수행할 수 있음

NumPy 연습 문제
라이브러리 참조하기
import numpy as np
배열 생성하기 : 리스트를 통한 1차원 배열 만들기
#리스트를 파라미터로 전달하여 ndarray 객체 생성
arr = np.array([1,3,5,7,9])
print(type(arr))
arr

배열의 크기
len() 함수를 사용하면 배열의 크기를 확인할 수 있다
arr = np.array([10,30,50,70,90])
size=len(arr)
print("배열의 원소는 %d 개 입니다" %size)

배열의 인덱싱과 슬라이싱
기본 특성은 리스트와 동일하기 때문에 리스트처럼 인덱싱과 슬라이싱이 가능하다
mydata = np.array([5,10,15,20,25])
#인덱싱을 사용한 원소 접근
print(mydata[0])
print(mydata[3])
print(mydata[4])
#슬라이싱을 사용한 구간 추출도 가능
print(mydata[1:4])
print(mydata[-4:-1])

반복문을 통한 활용
리스트와 동일하게 사용할 수 있다
mydata = np.array([100,110,120,130,140])
for i,v in enumerate(mydata):
print("%d 번쨰 원소 >> %d"%(i,v))

ndarray 의 특성
- list 의 경우 다른 데이터 타입의 원소를 허용하지만, ndarray 의 경우 가장 포괄적인 데이터 타입으로 변환한다
- 정수형은 "100." 형태로, boolean 은 False 는 0, True 는 1로 반환된다.
mylist =[100,3.14,True]
print("리스트에는 다양한 형태의 데이터가 들어올 수 있어요",mylist)
myarray =np.array(mylist)
print("배열은 다양한 형태의 데이터가 들어올 수 없어요",myarray)

2. ndarray 의 주요 기능
#numpy 라이브러리를 np 라는 이름으로 사용하도록 import
import numpy as np
ndarray 의 특성
- list 의 경우 다른 데이터 타입의 원소를 허용하지만, ndarray 의 경우 가장 포괄적인 데이터 타입으로 변환한다
- 정수형은 "100." 형태로, boolean 은 False 는 0, True 는 1로 반환된다.
mylist1 = [100.12,3.14,1.5]
myarr1=np.array(mylist1,dtype="int") #float 형태의 데이터들을 강제로 int 로 바꿔주니 소수점을 다 버림
myarr1

문자열이 포함된 경우의 형변환
- 모든 프로그래밍 언어에서 문자열은 표현 범위가 가장 넓은 데이터 타입이다
- 만약 배열로 변환하려는 리스트에 문자열이 하나라도 포함되어 있을 경우 모든 원소가 문자열이 된다
mylist2 = [1.2,3,True,'4']
myarr2 = np.array(mylist2)
myarr2

리스트 타입으로 역변환
- ndarray 와 list 는 서로 호환이 가능하다
- 만약 어떤 함수에서 파라미터로 리스트를 전송해야하면, 그 떄 ndarray 를 쓸 수 도 있다
mylist3 =[10,20,30,40,50]
myarr3 = np.array(mylist3) #리스트를 np.array 로 감싸주면 ndarray 타입이 된다
print(type(myarr3),myarr3)
mylist3_1 = list(myarr3) #ndarray 타입을 list() 함수로 감사주면 리스트 타입이 된다
print(type(mylist3_1),mylist3_1)

연산자를 사용한 ndarray 연산
- 리스트에서는 리스트를 더하면 [a,a,a,b,b,b] 이렇게 뒤에 이어지는 형태였지만 ndarray 에서는 원소의 위치에 대응되어 더해진다
arr1 = np.array([10,15,20,25,30])
arr2 = np.array([2,3,4,5,6])
print(arr1)
print(arr2)
# 더하기
a=arr1+arr2
print("arr+arr2 > ", a)
# 뺴기
b=arr1-arr2
print("arr-arr2 > ",b)
# 곱하기
c=arr1*arr2
print("arr*arr2 > ",c)
# 나누기
d=arr1/arr2
print("arr/arr2 > ",d)

NumPy 의 함수를 사용한 연산
연산자를 사용한 경우와 동일한 결과를 얻을 수 있는 내장 함수가 존재한다
arr1 = np.array([10,15,20,25,30])
arr2 = np.array([2,3,4,5,6])
print(arr1)
print(arr2)
# 더하기
a=np.add(arr1,arr2)
print("arr+arr2 > ", a)
# 뺴기
b=np.subtract(arr1,arr2)
print("arr-arr2 > ",b)
# 곱하기
c=np.multiply(arr1,arr2)
print("arr*arr2 > ",c)
# 나누기
d=np.divide(arr1,arr2)
print("arr/arr2 > ",d)

조건에 맞는 위치의 원소 추출
특정 배열에서 True 에 해당하는 값만 추출할 수도 있다
grade = np.array([82,77,91,88])
print("점수 리스트는" ,grade)
#추출하고자 하는 원본과 같은 사이트의 배열을 생성해서 True 와 False 로 구분해준다
bool_array = np.array([True,False,True,False])
print("구별 리스트는" , bool_array)
#True 에 해당하는 원소만 추출
result1 = grade[bool_array]
print("점수 리스트에서 True 에 해당한 원소들은",result1)

조건식에 따른 원소 추출
위의 예제처럼 True 에 해당하는 항목만 추출할 수 있었던 것처럼, 특정 조건에 해당하는 원소들만 추출하도록 조건을 세부화할 수 있다
# 80점 이상인 원소만 추출해보기
mypoint = np.array([82,77,91,88])
ge80 = mypoint[mypoint>=80]
print("80점이 넘는 원소들의 모음",ge80)
#2개 이상의 조건을 and 로 묶어줄 떄 쓸 수 있는 np.logical_and 함수
ge90and90 = mypoint[np.logical_and(mypoint>=80,mypoint<=90)]
print("80점 이상이면서 90점 이하인 점수" , ge90and90)
#2개 이상의 조건을 or 로 묶어줄 떄 쓸 수 있는 np.logical_or 함수
ge90or90 = mypoint[np.logical_or(mypoint<80,mypoint>90)]
print("80점보다 적거나 90점을 넘은점수" , ge90or90)

Numpy 조건 연산
sql 의 if() 함수와 동일한 결과를 만들고, 파생 변수를 만들 때 유용한 npl.where 함수
exam = np.array([60,83,75,92,86])
#np.where 의 첫 파라미터로 주어진 조건이 참이면 합격, 아니면 불합격
result = np.where (exam>=80,"합격","불합격")
result

여러 조건 한번에 처리하기
exam = np.array ([60,85,51,79,94,88])
#학점을 부여하기 위한 점수의 구건을 설정하는 조건들을 리스트로 설정
conditions = [ (exam >= 90),
(exam >= 80),
(exam >=70)
]
#조건에 따라 부여될 학점
value = ["A","B","C"]
result = np.select(conditions,value,default='F') #기본 값을 F 로 설정
result

3. 그 밖의 ndarray 형태
2차원 배열
2차원 리스트를 ndarray 로 변환한다. ( 배열의 정보를 확인할 수 있는 프로퍼티가 포함된다)
- 차원의 크기 : ndim
- 차원별 원소수 : shape
- 원소의 데이터 타입 : dtype
myarray = np.array([
[98,72,80,64],
[88,90,80,72],
[92,88,92,76]
])
print(myarray)
print("차원 크기:", myarray.ndim)
print("차원별 원소수:", myarray.shape)
print("원소의 데이터 타입:", myarray.dtype)

boolean 타입으로 인덱싱
조건에 맞는 원소를 1차원 배열로 반환한다
# 1) Boolean 인덱싱: 조건에 맞는 항목만 1차원으로 추출
bool_array = np.array([
[True, False, True, False],
[True, True, True, False],
[True, True, True, False]
])
#True 에 해당하는 원소만 출력되고, 조회한 형태는 2차원 데이터더라도 결과는 1차원으로 추출된다
result1 = myarray[bool_array]
print("result1:", result1)

비교식에 의한 검색
조건에 맞는 원소를 1차우너 배열로 반환하고, 여기서도 and 와 or 조건을 활용할 수 있다
result2 = myarray[myarray >=80]
print("점수가 80점 이상인 원소들이 1차원 배열로 출력됩니다 : ",result2)
#and 조건은 logical_and()
result3=myarray[np.logical_and(myarray>=80,myarray <=90)]
print("점수가 80점 이상 이면서 90점 이하인 경우는 다음과 같습니다:",result3)
#or 조건은 logical_or()
result4=myarray[np.logical_or(myarray <80,myarray >90)]
print("점수가 80점 미만이거나 90점을 초과한 경우는 다음과 같습니다",result4)

정형화된 특수한 형태의 배열 생성하기
#모든 원소가 0인 배열
np.zeros([3,4])
#모든 원소가 1인 배열
np.ones([3,4])
#모든 원소가 특정 값인 배열
np.full([3,4],10)
#단위 행렬 (대각선 원소가 모두 1이고 그 외는 모두 0인 배열)
np.eye(4)

랜덤 배열
0부터 1 범위에서 균등하게 추출하여 N 차원 랜덤 배열 생성
#10개의 값을 갖는 1차원 배열
np.random.rand(10)
# 4행 3열인 2차원 랜덤 배열 생성 (첫 파라미터는 행, 두번쨰 파라미터는 열)
np.random.rand(4,3)

주어진 범위 안에서 정수값을 갖는 랜덤 배열
특정 범위를 지정해줄 수도 있다
# 0-9 사이의 랜덤값 10개의 원소를 갖는 1차원 배열
np.random.randint(0,9,10)
#0-9 사이틔 랜덤값을 갖는 3행 4열의 2차 배열
np.random.randint(0,9,(3,4))

랜덤 시드 고정
np.random.seed(1234)
np.random.normal(0,1,(4,3))

표준 정규 분포를 따르는 랜덤 배열
rand 뒤에 n 이 붙어있는 메서드를 사용하면 표준 정규 분포를 따르는 형태로 숫자가 랜덤 부여된다
np.random.randn(10)
np.random.randn(4,3)
