[파이썬] Numpy - 배열과 벡터 계산

2021. 6. 27. 17:51공부한 내용/파이썬 문법

1. 1차원 배열

-numpy의 array라는 함수를 통해 배열로 변환

1) 배열 생성과 형태

(1) 1차원 배열 생성

arr = np.array([0,1,2,3,4,5])

 

(2) 배열의 형태(크기) 확인

arr.shape
#> (6,)

 

(3) 데이터 타입(자료형) 확인

arr.dtype
#> dtype('int64')

 

2) 벡터화 연산

#배열 생성
data = np.array([0,1,2,3,4,5])

#배열과 스칼라 덧셈
data + 2
#> array([2,3,4,5,6,7])

#배열과 스칼라 곱셈
data * 2
#> array([0,2,4,6,8,10])

#배열과 스칼라 나눗셈의 몫
data // 2
#> array([0,0,1,1,2,2])

#array 배열끼리 계산
a = np.array([1,2,3])
b = np.array([10,20,30])

2 * a + b
#> array([12,24,36])

b - a
#> array([9,18,27])

 

3) 조건(True, Fales) 연산

a == 2
#> array([False, True, False])

b > 10
#> array([False, True, True])

[a == 2] & [b > 10]
#> array([False, True, False])

 

 

2. 다차원 배열

-다차원 배열 자료 구조 (ex)1차원, 2차원, 3차원 배열

-2차원 배열은 행렬(matrix)로 행(row)와 열(column)로 구성

 

1) 2차원 배열

c = np.array([[0,1,2],[3,4,5]])
# (2x3) 배열

#행의 개수 확인
len(c)
#> 2

#열의 개수 확인
len(c[0])
#> 3

 

2) 3차원 배열

-크기를 나타낼 때는 가장 바깥족 리스트의 길이부터 가장 안쪽 리스트 길이의 순서로 표시한다.

(행 x 열 x 깊이)

d = np.array([[[1,2,3,4],
		[5,6,7,8],
        [9,10,11,12]],
        [[11,12,13,14],
        [15,16,17,18],
        [19,20,21,22]]])

#행 개수 확인
len(d)
#> 2

#열 개수 확인
len(d[0])
#> 3

#깊이 확인
len(d[0][0])
#> 4

 

 

3. 배열의 크기와 차원

-ndim 속성은 배열의 차원, shape 속성은 배열의 크기를 반환

#1차원 배열
ab = np.array([1,2,3])

ab.ndim
#> 1

ab.shape
#> (3,)


#2차원 배열
abc = np.array([[0,1,2],[3,4,5]])

abc.ndim
#> 2

abc.shape
#> (2,3)


#3차원 배열
abcd = np.array([[[1,2,3,4],
		[5,6,7,8],
            [9,10,11,12]],
            [[11,12,13,14],
            [15,16,17,18],
            [19,20,21,22]]])

abcd.ndim
#> 3

abcd.shape
#> (2,3,4)

 

 

4. 배열의 인덱싱

1) 1차원 배열의 인덱싱

a = np.array([1,2,3,4])

a[2]
#> 3

 

2) 다차원 배열의 인덱싱

-배열 객체로 구현한 다차원 배열의 원소 중 "하나"의 개체를 선택

-콤마로 구분된 차원을 축(axis)이라 하며, 그래프의 (x,y)축과 동일

b = np.array([[0,1,2],[3,4,5]])

#첫번째 행, 첫번째 열
b[0,0]
#> 0

#첫번째 행, 두번째 열
b[0,1]
#> 1

#마지막 행, 마지막 열
b[-1,-1]
#> 5

 

3) 배열의 불리언 인덱싱

-불리언 배열 인덱싱 방식은 인덱스 배열의 원소가 True, False 두 값으로만 구성

-인덱스 배열의 크기가 원래 np.array 객체와 동일하다는 조건 하에 가능

a = np.array([0,1,2,3,4])
idx = np.array([True, False, True, False, True])

a[idx]
#> array([0,2,4])

a % 2 == 0
#> array([True, False, True, False, True])

a[a % 2 == 0]
#> array([0,2,4])

 

 

5. 배열의 슬라이싱

-배열 객체로 구현한 다차원 배열의 원소 중 복수 개를 선택

-일반적인 파이썬의 슬라이싱(slicing)과 comma(,)를 함께 사용

a = np.array([[0,1,2,3],[4,5,6,7]])

a[0, :]
#첫번째 행 전체

a[:, 1]
#두번째 열 전체

a[:2, :2]
#첫번째 행 2열, 두번째 행 2열

 

 

6. Numpy 배열 데이터 타입

-ndarray클래스는 데이터가 같은 자료형

-array 명령으로 배열을 만들 때 자료형 지정은 dtype 사용

 

(Type ; Type Code)

*bool형

-bool ; ?

 

*정수형

-int8 ; i1

-int16 ; i2

-int32 ; i4

-int64 ; i8

 

*부호없는 (양수) 정수형

-uint8 ; u1

-uint16 ; u2

-uint32 ; u4

-uint64 ; u8

 

*부동소수형

-float16 ; f2

-float32 ; f4

-float64 ; f8

 

*복소수형(실수+허수)

-complex64 ; c8

-complex128 ; c16

 

*문자형

-string_ ; s

a = np.array([1,2,3])
a.dtype
#> dtype('int64')

b = np.array([1.0, 2.0, 3.0])
b.dtype
#> dtype('float64')

c = np.array([1, 2, 3.0])
c.dtype
#> dtype('float64')

d = np.array([1,2,3], dtype="f")
d.dtype
#> dtype('float32')

 

 

7. Numpy inf와 nan & 로그/지수함수

1) inf, nan

-무한대를 표현하기 위한 np.inf(infinity)와 정의할 수 없는 숫자를 나타내는 np.nan(not a number)

np.array([0,1,-1,0]) / np.array([1,0,0,0])
#> array([0, inf, -inf, nan])

 

2) 로그함수 & 지수함수

#로그함수
np.log(0)
#> -inf

np.exp(-np.inf)
#> 0.0

 

 

8. 배열 생성 - zeros, ones, arange

1) np.zeros

a = np.zeros(5)

a
#> array([0., 0., 0., 0., 0.])   #실수형 0

a.dtype
#> dtype('float64')

#0으로 된 2x3 2차원 배열 생성
b = np.zeros((2,3))

b.dtype
#> dtype('float64')

#0으로 된 5x2 정수형 배열 생성(명시하지 않으면 실수)
c = np.zeros((5,2), dtype='i')
# (5x2) 크기의 정수형 배열 생성

 

2) np.ones

-1로 초기화된 배열을 생성

e = np.ones((2,3,4), dtype='i8')

 

3) np.arange

-Python 기본 명령어 range와 같은 특정한 규칙에 따라 증가하는 소열을 생성

np.arange(10)
#> array([0,1,2,3,4,5,6,7,8,9])

np.arange(3,21,2)
#> array([3,5,7,9,11,13,15,17,19])

 

4) 전치 연산

-행과 열을 바꾸는 전치(transpose) 연산으로 t 속성 사용

a = np.array([[1,2,3], [4,5,6])
# 3x2 배열

a.T
# 2x3 배열

 

5) 배열의 크기 변환

-만들어진 배열의 내부 데이터는 보존한 채로 형태만 reshape 명령이나 메서드로 변형

a  = np.arange(12)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

b = a.reshape(3, 4)
# array([[0, 1, 2, 3],
#      [4, 5, 6, 7],
#      [8, 9, 10, 11]])

#-1을 사용하여 동일하게 변형
b.reshape(3, -1)
#> array([[0, 1, 2, 3],
#      [4, 5, 6, 7],
#      [8, 9, 10, 11]])

 

 

9. 배열의 연산

1) 벡터화 연산(vectorized operation)

x = np.arange(1, 10001)
y = np.arnage(10001, 20001)

z = x + y
z
#> array([10002, 10004, ..., 29998, 30000])

 

2) 지수, 제곱, 로그함수 연산

a = np.arange(5)

#지수함수
np.exp(a)
#> array([1, 2.71828, 7.38905, 20.08553, 54.59815])

#10에 a승 취함
10 ** a
#> array([1, 10, 100, 1000, 10000])

#로그함수
np.log(a+1)
#> array([0, 0.69314, 1.09861, 1.38629, 1.60943])

 

3) 스칼라와 벡터 연산

x = np.arange(10)

100 * x
#> array([0, 100, 200, 300, 400, 500, 600, 700, 800, 900])

x = np.arange(12).reshape(3, 4)
100 * x
#> array([[0, 100, 200, 300],
#      [400, 500, 600, 700],
#      [800, 900, 1000, 1100]])

 

4) 브로드캐스팅(Broadcasting)

-벡터 연산 시에 두 벡터의 크기가 동일해야 한다.

-서로 다른 크기를 가진 두 배열의 사칙 연산은 브로드캐스팅(broadcasting)으로 크기가 작은 배열을 자동으로 반복 확장하여 크기가 큰 배열에 맞춰준다.

-벡터+스칼라인 경우, 스칼라를 벡터와 같은 크기로 확장시켜서 덧셈 계산

x = np.array([[0, 1, 2], [1, 2, 3], [2, 3, 4], [4, 5, 6]])
y = np.arange(3)

x + y
#> array([[0, 2, 4], [1, 3, 5], [2, 4, 6], [4, 6, 8]])

x + 1
#> array([[1, 2, 3], [2, 3, 4], [3, 4, 5], [5, 6, 7]])

 

 

10. 차원축소 연산

-차원 축소(Dimension Reduction) 연산은 행렬의 하나의 행에 있는 원소들을 하나의 데이터 집합으로 보고 그 집합의 평균을 구하면 1차원 벡터가 반환

 

*Numpy의 차원 축소 연산 메서드

-최대/최소: min, max, argmin, argmax

-통계: sum, mean, median, std, var

-불리언: all, any

 

1) 1차원 배열의 차원축소 연산

x = np.array([1, 2, 3, 4])

np.sum(x) #x.sum()도 가능
#> 10

x.min()
#> 1

x.max()
#. 4

#최소값의 위치 반환
x.argmin()
#> 0

#최대값의 위치 반환
x.argmax()
#> 3

x.mean()
np.median(x)  #x.median()도 가능

 

2) 2차원 배열의 차원축소 연산

-연산의 대상이 2차원 이상인 경우에는 어느 차원으로 계산할 지를 axis 인수를 사용하여 지정

-axis=0인 경우는 열 연산, axis=1인 경우는 행 연산 (default 값은 axis=0)

x = np.array([[1, 3], [2, 4]])

x.sum()
#> 10

#axis=0 인자를 사용하여 열 합계 구하기
x.sum(axis=0)
#> array([3, 7])

#axis=1 인자를 사용하여 행 합계 구하기
x.sum(axis=1)
#> array([4, 6])

 

 

11. Numpy를 이용한 기술통계(descriptive statistics)

x = np.array([18, 5, 10, 23, 19, -5, 10, 0, 0, 5, 2, 126, 8, 2, 5, 5, 15, -3, 4, -1, -20 ,8, 9, -4, 25, -12])

#데이터 개수
len(x)
#> 26

#평균값
np.mean(x)
#> 9.76923076923077

#분산값
np.var(x)
#> 637.9467455621302

#표준편차
np.std(x)
#> 25.257607676938253

#최대값
np.max(x)
#> 126

#최소값
np.min(x)
#> -20

#중앙값
np.median(x)
#> 5.0

 

 

12. Numpy 난수생성

*데이터를 무작위로 섞거나 임의의 수, 즉 난수(random number)를 발생시키는 numpy의 random 서브패키지 사용 명령어는:

-rand: 0부터 1사이의 균일 분포

-randn: 가우시안 표준 정규 분포

-randint: 균일 분포의 정수 난수

# rand로 1차원 배열 난수 생성
np.random.rand(10)
#> array([9.80114329e-01, 7.33486865e-01, 8.84953666e-04, 6.56479127e-01, 3.60124550e-01, 2.82663073e-01, 5.02073274e-01, 6.37992651e-01, 2.67115693e-01, 6.45095731e-01])

# rand로 3x2 배열 난수 생성
np.random.rand(3, 2)
#> array([[0.57697406, 0.10174202],
#         [0.43666112, 0.30022151],
#         [0.09264312, 0.39533411]])

 

*randint

: numpy.random.randint(low, high=none, size=none)
(만약 high를 입력하지 않으면 0과 low사이의 숫자를, high를 입력하면 low와 high는 사이의 숫자를 출력하고, size는 난수의 숫자)

#10부터 20까지 1차원 배열 생성
np.random.randint(10, 20, size=10)
#> array([19, 15, 14, 19, 18, 13, 11, 18, 18, 16])


#10부터 20까지 3x5 배열 생성
np.random.randint(10, 20, size=(3, 5))
#> array([[11, 17, 19, 12, 17],
#        [19, 18, 18, 19, 12],
#        [12, 17, 14, 13, 10]])