반응형

Numpy 배열 결합

 

# 배열 결합
print(x, end='\n\n')
print(y, end='\n\n')

arrhap = np.concatenate([x,y])
print(arrhap, end='\n\n')
x1, x2 = np.split(arrhap,2)
print(x1, end='\n\n')
print(x2, end='\n\n')

a = np.arange(1, 17).reshape(4,4)
print(a, end='\n\n')

x1, x2 = np.hsplit(a,2)
print(x1, end='\n\n')
print(x2, end='\n\n')

x1, x2 = np.vsplit(a,2)
print(x1, end='\n\n')
print(x2, end='\n\n')



# 출력 결과

[1 2 3]

[4 5 6]

[1 2 3 4 5 6]

[1 2 3]

[4 5 6]

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [13 14 15 16]]

[[ 1  2]
 [ 5  6]
 [ 9 10]
 [13 14]]

[[ 3  4]
 [ 7  8]
 [11 12]
 [15 16]]

[[1 2 3 4]
 [5 6 7 8]]

[[ 9 10 11 12]
 [13 14 15 16]]

 

1차원 배열인 x와 y 배열을 생성해줍니다.

arrhap 에 x,y 배열을 합친후 결과를 출력한 결과 1차원 배열을 리스트로 반환해주었습니다.

이것을 다시 x1과 x2에 split 함수를 사용하여 분리해주었습니다.

 

더 잘게 split을 사용할 경우 앞에 사용할 변수 명을 추가해준 다음,

split함수 옵션에 (나눌배열,나눌개수)를 사용해주도록 합니다.

 

a에 1~16의 숫자를 입력 후 4x4 행렬로 생성 후

hspit(나눌배열, 나눈배열그룹개수) : 지정한 배열을 수평(행) 방향으로 분할

vsplit(나눌배열, 나눈 배열 그룹 개수) : 지정한 배열을 수직(열) 방향으로 분할

 

저는 2그룹씩 분할을 하였기때문에 위와같은 결과가 생성됩니다.

 

 

반응형
반응형

Numpy 배열 행 열 추가 및 삭제

 

# 배열에 행열 추가 삭제
import numpy as np

aa = np.eye(3)
print(aa, end='\n\n')
bb = np.c_[aa, aa[2]] # 열 추가 2번째 열을 하나 더 추가 후 출력
print(bb, end='\n\n')

cc = np.r_[aa, [aa[2]]] # 2번째 행 추가 후 출력
print(cc, end='\n\n')

a = np.array([1,2,3])
print(a, end='\n\n')
print(np.c_[a], end='\n\n')
print(a.reshape(3,1), end='\n\n')


# 출력 결과

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 1.]]

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [0. 0. 1.]]

[1 2 3]

[[1]
 [2]
 [3]]

[[1]
 [2]
 [3]]

 

eye 함수는 이전에 포스팅하였습니다!

2020/05/31 - [python] - [Python] Numpy (2) - zeros, ones, full, eye, 난수

 

[Python] Numpy (2) - zeros, ones, full, eye, 난수

2020/05/28 - [python] - [python] Numpy [python] Numpy Numpy 란? C언어로 개발되었으며, 계산을 위한 라이브러리로서 다차원 배열을 처리하는데 필요한 기능을 제공합니다. Numpy 데이터 타입 # numpy : ndarra..

lightchan.tistory.com

 

eye 함수로 3 x 3 행렬을 생성 후,

 

.c_ 를 사용하면 열을 추가한다는 의미로, 

위 소스코드에서는 aa 배열의 열에 2번째 열을 추가해주겠다는 의미입니다.

 

.r_ 를 사용하면 행을 추가해주겠다는 의미로, 위 소스코드에서는 2번째 행을 aa 행렬에 추가해주겠다는 의미입니다.

 

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

print(a, end='\n\n')
#b = np.append(a,[4,5])
b = np.append(a, [4,5], axis = 0)
print(b, end='\n\n')

c = np.insert(a,0, [6,7], axis=0) 
print(c, end='\n\n')

d = np.delete(a, 1) # 1열 삭제
d = np.delete(a,[1])
print(d, end='\n\n')


# 출력 결과

[1 2 3]

[1 2 3 4 5]

[6 7 1 2 3]

[1 3]

 

append 함수 :  리스트의 맨 마지막에 값을 추가해주는 함수이다.

위 소스에서 a라는 1차원 배열 리스트에 4와 5를 추가해주었습니다.

 

insert 함수 : 리스트에 요소를 추가해주는 함수로 0 번째 위치에 6과 7을 더해준다는 의미입니다.

 

delete 함수 : 1차원 배열 a의 1열을 삭제한다는 의미입니다.

 

 

aa = np.arange(1, 10).reshape(3,3) # 2차원 배열
print(aa, end='\n\n')

print(np.insert(aa, 1, 99), end='\n\n')
print(np.insert(aa,1, 99, axis=0), end='\n\n')


# 출력 결과
[[1 2 3]
 [4 5 6]
 [7 8 9]]

[ 1 99  2  3  4  5  6  7  8  9]

[[ 1  2  3]
 [99 99 99]
 [ 4  5  6]
 [ 7  8  9]]

 

aa라는 변수에 1차원 배열 1부터 9까지 삽입 후 reshape 함수를 통해 2차원배열인 3x3로 변경해주었습니다.

 

그리고, insert 함수에 axis 옵션을 주지 않으면 1차원 배열로 1번째 위치의 값을 99로 변경하는 의미입니다.

그 다음 출력문에는 axis=0 으로 행을 의미하며 1행 전부의 값을 99로 변환하는 의미입니다.

 

delete문은 insert 함수와 반대로 생각하시면 됩니다.

 

print(aa, end='\n\n')
print(np.delete(aa, 1), end='\n\n') # 0행 1열 값을 지움
print(np.delete(aa, 1, axis = 0), end='\n\n') # 1행을 지움
print(np.delete(aa, 1, axis = 1), end='\n\n') # 1열을 지움


# 출력 결과

[[1 2 3]
 [4 5 6]
 [7 8 9]]

[1 3 4 5 6 7 8 9]

[[1 2 3]
 [7 8 9]]

[[1 3]
 [4 6]
 [7 9]]

 

Numpy 내장 함수

ex =  np.random.randn(5,4)
print(ex, end='\n\n')

print('1행의 합과 최대값')
print(np.sum(ex[0],))
print(np.max(ex[0],), end='\n\n')

print('2행의 합과 최대값')
print(np.sum(ex[1],))
print(np.max(ex[1],), end='\n\n')

print('3행의 합과 최대값')
print(np.sum(ex[2],))
print(np.max(ex[2],), end='\n\n')


c = np.zeros((6, 6))
print(c, end='\n\n')

num = 1
for i in range(len(c[0])):
  for j in range(len(c[0])):
    c[i][j] = num
    num += 1

print('1~36 채우기')
print(c, end='\n\n')

print('2번째 행 전체 원소 출력')
print(c[1], end='\n\n')

print('5번째 열 전체 원소 출력')
print(c[:,4], end='\n\n')

print('부분 출력')
print(c[2:5,2:5], end='\n\n')


print('2-2번')

b = np.zeros((6,4))
c = np.random.randint(20, 100, 6)

for i in range(6):
  for j in range(3):
       b[i][0] = c[i]
       b[i][j+1] = b[i][j]+1
 

print(b)

b[0] = 1000
b[5] = 6000

print(b)


print('3번')
ex1 =  np.random.randn(4,5)
print(ex1, end='\n\n')

print('평균 : ',np.mean(ex1), end='\n\n')
print('합계 : ',np.sum(ex1), end='\n\n')
print('표준편차 : ',np.std(ex1), end='\n\n')
print('분산 : ',np.var(ex1), end='\n\n')
print('최대값 : ',np.max(ex1), end='\n\n')
print('최소값 : ',np.min(ex1), end='\n\n')
print('1사분위 : ',np.percentile(ex1,25), end='\n\n')
print('2사분위 : ',np.percentile(ex1,50), end='\n\n')
print('3사분위 : ',np.percentile(ex1,75), end='\n\n')
print('요소값누적합 : ',np.cumsum(ex1), end='\n\n')


# 출력 결과

[[-0.99017343 -1.26807787  0.61941937  0.40683047]
 [-1.03161855 -1.23595668  1.54022423 -0.74237974]
 [-1.55127342  1.67563386 -0.97895193  1.70391295]
 [-1.23341949  0.09689477 -0.50175499 -0.63970651]
 [ 0.17859581 -1.74168996 -0.8277483   0.23756665]]

1행의 합과 최대값
-1.2320014629208895
0.6194193744851698

2행의 합과 최대값
-1.4697307416436023
1.5402242284791654

3행의 합과 최대값
0.8493214631503689
1.7039129520342273

[[0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0.]]

1~36 채우기
[[ 1.  2.  3.  4.  5.  6.]
 [ 7.  8.  9. 10. 11. 12.]
 [13. 14. 15. 16. 17. 18.]
 [19. 20. 21. 22. 23. 24.]
 [25. 26. 27. 28. 29. 30.]
 [31. 32. 33. 34. 35. 36.]]

2번째 행 전체 원소 출력
[ 7.  8.  9. 10. 11. 12.]

5번째 열 전체 원소 출력
[ 5. 11. 17. 23. 29. 35.]

부분 출력
[[15. 16. 17.]
 [21. 22. 23.]
 [27. 28. 29.]]

2-2번
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]

3번
[[ 0.21862159  2.23607505 -0.56159948  2.0627482  -1.35312291]
 [-0.45196089  2.38118527  0.54214996  0.29531398 -1.3756751 ]
 [ 0.11210441  1.60344909  0.71672278  1.10790232  0.41659081]
 [-1.28873769 -0.26544286  0.01087163 -1.22702418  0.02647448]]

평균 :  0.2603323229168358

합계 :  5.206646458336715

표준편차 :  1.1396837454447413

분산 :  1.298879039630954

최대값 :  2.38118527114613

최소값 :  -1.3756751031190795

1사분위 :  -0.4793705371100291

2사분위 :  0.16536299941867438

3사분위 :  0.8145176683660762

요소값누적합 :  [0.21862159 2.45469664 1.89309716 3.95584536 2.60272245 2.15076156
 4.53194683 5.07409679 5.36941077 3.99373567 4.10584008 5.70928917
 6.42601195 7.53391427 7.95050508 6.66176739 6.39632453 6.40719616
 5.18017198 5.20664646]
반응형
반응형

Numpy broadcasting

 

벡터의 내적을 구할 때는 차원이 서로 같아야만 하는 조건이있었습니다.

 

하지만 이번 브로드캐스트는 다른 차원의 연산이 가능한 점에서 차이가 있습니다.

 

우선 3가지 방법을 소개해드리면 다음과 같습니다.

1번 for문 // 2번 tile 함수 이용 // 마지막으로 자동 브로드 캐스팅 방법이있습니다.

 

numpy.empty(배열, dtype='조건')

- 특정한 값으로 초기화하지 않는 배열을 생성

 

numpy.empty_like(배열, dtype='조건')

- 배열의 크기와 동일하며 특정한 값으로 초기화하지 않는 배열을 생성

 

import numpy as np

x = np.arange(1, 10).reshape(3,3)
y = np.array([1,0,1])
z = np.empty_like(x)

print(x, end='\n\n')
print(y, end='\n\n')
print(z, end='\n\n')

# x + y
for i in range(3):
  z[i] = x[i] + y
print(z, end='\n\n')  

# 방법 2 tile()
kbs = np.tile(y, (3,1))
print(kbs, end='\n\n')
z = x + kbs
print(z, end='\n\n')

# 방법 3 nuympy 의 broadcast
mbc = x + y
print(mbc + 100, end='\n\n')


# 출력 결과

[[1 2 3]
 [4 5 6]
 [7 8 9]]

[1 0 1]

[[1 2 3]
 [4 5 6]
 [7 8 9]]

[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]]

[[1 0 1]
 [1 0 1]
 [1 0 1]]

[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]]

[[102 102 104]
 [105 105 107]
 [108 108 110]]

 

x 행렬을 다음과 같이 주고 empty_like 함수를 사용하여 z 행렬을 그대로 복사하였습니다.

 

이후, 1번 방법 for문을 사용한 경우 각 행의 자리에 맞춰 1차원 배열인 y 값들을 더해 준 것을 확인 할 수 있습니다.

 

방법 2번 tile을 이용하여 구조를 맞추는 방식으로 3행과 길이는 1로 2차원 배열을 생성한 후 z 배열에 더한 것입니다.

만약 길이를 2로 주었다면 [ 1 0 1 1 0 1 ] 이 3행까지 반복되어서 출력되었을 것입니다.

 

방법 3번 자동 브로드 캐스팅 사용

자동으로 자리를 맞추어 값을 계산하여 출력합니다.

 

# broadcast ex
v = np.array([1,2,3])
w = np.array([4,5])

print(np.reshape(v, (3,1))*w, end='\n\n')
print(np.reshape(w, (2,1))*v, end='\n\n')

x = np.array([[1,2,3],[4,5,6]])
print(x, end='\n\n')
print(x+y, end='\n\n')
#print(x+w, end='\n\n') # 브로드캐스팅 불가능
print(x.T , end='\n\n')
print(x.T + w, end='\n\n')
print((x.T + w).T, end='\n\n')


# 출력 결과

[[ 4  5]
 [ 8 10]
 [12 15]]

[[ 4  8 12]
 [ 5 10 15]]

[[1 2 3]
 [4 5 6]]

[[2 2 4]
 [5 5 7]]
 
 [[1 4]
 [2 5]
 [3 6]]

[[ 5  9]
 [ 6 10]
 [ 7 11]]

[[ 5  6  7]
 [ 9 10 11]]

 

1행 3열 배열을 3행 1열로 바꾸어 내적하여 계산하였습니다. 

그 다음 라인에서는 w의 1행 2열 배열을 2행 1열로 내적하여 계산하였습니다.

 

행열의 구조를 변경하는 방법으로 .T 를 사용할 수도 있습니다.

x 행렬은 2행 3열짜리 배열로 구조를 잡아주었습니다.

 

x.T 를 사용하여 3행 2열짜리의 배열로 구조가 변경 된 것을 확인 하실 수 있습니다.

 

반응형
반응형

Numpy Sum 함수

말 그대로 각각의 값들을 더하는 함수입니다.

x = np.array([[1,2], [3,4]])
print(x, end='\n\n')
print(np.sum(x), end='\n\n')
# axis = 0 열 기준으로 계산 // axis = 1 행 기준으로 계산
print(np.sum(x, axis = 0), end='\n\n') # 1 + 3 = 4 , 2 + 4 = 6 
print(np.sum(x, axis = 1), end='\n\n')
print(np.cumsum(x), end='\n\n')


# 출력 결과

[[1 2]
 [3 4]]

10

[4 6]

[3 7]

[ 1  3  6 10]

 

해당 소스코드에서 SUM 함수는 각각의 행과 열에 있는 값들을 다 더한 것을 확인하실 수 있습니다.

행과 열을 각각 따로 더하고 싶다면 뒤에 axis 조건을 주어 0인 경우 열을 기준으로 더하고 1인 경우 행을 기준으로 더합니다.

 

Numpy 집합

각각의 집합관련 함수는 다음과 같습니다.

unique(x) : 배열 값들 중 중복된 원소 제거하고, 유일한 원소를 반환

intersect1d(x, y) : 두 배열 x, y 의 교집합을 반환

union1d(x, y) : 두 배열 x, y의 합집합을 반환

setdiff1d(x, y) : x 배열 로 부터 배열 y를 뺀 차집합을 반환

setxor1d(x, y) : x, y 배열의 합집합에서 교집합을 뺀 대칭차집합을 반환

 

x = np.array(['a','b','a','c'])
y = np.array(['a','d','e'])

# unique
print('unique', ' ',np.unique(x), end='\n\n') # 중복되는 값은 1개만 출력

# 차집합
print('setdiff1d ', np.setdiff1d(x,y), end='\n\n')

print(set(x), end='\n\n') # 

# 교집합 합집합
# 교집합 , 중복되는 값만 출력 assume_unique 작성시 중복가능
print('intersect1d ' , ' ', np.intersect1d(x, y, assume_unique=True), end='\n\n')
# 합집함 , 중복을 허용하지 않고 5개의 값 다 출력
print('union1d ' , ' ' , np.union1d(x, y), end='\n\n') 



# 출력 결과

unique   ['a' 'b' 'c']

setdiff1d  ['b' 'c']

{'b', 'c', 'a'}

intersect1d    ['a' 'a']

union1d    ['a' 'b' 'c' 'd' 'e']

 

 

* arange함수와 reshape 함수

 

arange 함수는 range는 리스트로 반환합니다. arange 함수는 range 함수와 사용하는 방법은 동일하나 리턴을 배열로합니다.

 

reshape 함수는 예를 들어 1차원 배열로 출력한 것을 reshape 함수를 통해 2차원 배열로 변경하는데 사용되곤 합니다.

 

aa = np.arange(12) # 1차원 배열
bb = aa.reshape(3,4) # 1차원 배열인 a를 2차원 배열로 변경
print(aa, end='\n\n') # 1차원 배열
print(bb, end='\n\n')

# 출력 결과

[ 0  1  2  3  4  5  6  7  8  9 10 11]

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
반응형
반응형

Numpy 배열 연산

 

# 배열 연산
import numpy as np

x = np.array([[1,2], [3,4]])
y = np.arange(5, 9).reshape((2,2)) 
y = y.astype(np.float32)
print(x, type(x), x.dtype)

print(y, type(y), end='\n\n')

print(x+y, end='\n\n') # + 연산

print(np.add(x,y), end='\n\n') # + 연산

print(np.subtract(x,y), end='\n\n') # - 연산

print(x-y, end='\n\n') # - 연산

print(np.divide(x,y), end='\n\n') # / 연산

print(x*y, end='\n\n') # * 연산


# 출력 결과

[[1. 2.]
 [3. 4.]]
 
[[5. 6.]
 [7. 8.]]

[[ 6.  8.]
 [10. 12.]]

[[ 6.  8.]
 [10. 12.]]

[[-4. -4.]
 [-4. -4.]]

[[-4. -4.]
 [-4. -4.]]

[[0.2        0.33333334]
 [0.42857143 0.5       ]]

[[ 5. 12.]
 [21. 32.]]

 

행렬의 연산은 자리끼리 연산해주기 때문에 쉽게 해결하실 수 있습니다.

 

연산 결과를 보기에 앞서, reshape 라는 함수가 존재합니다.

 

reshape 함수란 배열의 차원의 크기를 변경하는 방법으로, 배열의 요소의 개수는 동일하고 배열의 차원만 변경해줍니다.

 

덧셈 -> add(배열1, 배열2) , add 대신 + 사용 가능합니다.

뺄셈 -> subtract(배열1, 배열2) , subtract 대신 - 사용 가능합니다.

곱셉 -> multiply(배열1, 배열2) , multiply 대신 * 사용 가능합니다.

나눗셈 -> divide(배열1, 배열2) , divide 대신 / 사용 가능합니다.

 

Numpy 벡터의 내적

 

벡터의 내적 함수에 대하셔 내적 계산시에는 dot 메소드를 필요로합니다.

 

형태는 다음과 같습니다.

z = dot(x,y)
z = dot(x,y,dim)

 

- 내적 함수를 계산하려면 열과 행이 일치하여야하고 만약, 일치하지 않는다면 가공을 필요로 하고 T(transform)를 이용합니다.

 

- 2차원 배열을 벡터 계산하면 1차 배열의 결과가 나오고, 1차 배열을 벡터계산하면 스칼라 결과가 출력됩니다.

 

import numpy as np
v = np.array([9,10])
w = np.array([11,12])

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

print(v.dot(w), end='\n\n') 
print(np.dot(v, w), end='\n\n') 

print(np.dot(x, y), end='\n\n')


# 출력 결과

219

219

[[19. 22.]
 [43. 50.]]

 

v.dot(w) 의 경우 v와 w의 내적함수를 구한 것으로 (9 *11) + (10*12) 를 하여 219가 출력된 것입니다.

 

위와 동일한 식으로 np.dot(v, w) 가 있습니다. 위와 계산 방식은 동일하기에 출력 결과도 같습니다.

 

2차원 배열의 경우

 

( 1 * 5 ) + ( 2 * 7 ) = 19 값은 1행 1열에 저장

 

( 1 * 6 ) + ( 2 * 8 ) = 22 값은 1행 2열에 저장

 

( 3 * 5 ) + ( 4 * 7 ) = 43 값은 2행 1열에 저장

 

( 3 * 6 ) + ( 4 * 8 ) = 50 값은 2행 2열에 저장이 됩니다.

 

 

반응형
반응형

배열 관련 포스팅

 

2020/05/28 - [python] - [python] Numpy 데이터타입, 메모리저장, 배열

 

[python] Numpy 데이터타입, 메모리저장, 배열

Numpy 란? C언어로 개발되었으며, 계산을 위한 라이브러리로서 다차원 배열을 처리하는데 필요한 기능을 제공합니다. Numpy 데이터 타입 # numpy : ndarray import numpy as np nn = [1, 2, 3.5] nn1 = (6,7,8,9)..

lightchan.tistory.com

 

 

 

Numpy 슬라이싱

a = np.array([1,2,3,4,5])
print(a, type(a), end='\n\n')
print(a[1], end='\n\n')
print(a[1:5:2], end='\n\n')
print(a[-5:-2], end='\n\n')
print(a[1:], ' ' , a[:3], end='\n\n')

print('==========================')

a = np.array([[1,2,3,4], [5 ,6,7,8], [9,10,11,12]])
print(a, a.shape, end='\n\n')
#print(a[:])
print(a[1:], end='\n\n')
print(a[0], a[0][0],a[0,0], a[[0]], end='\n\n')
print(a[0,0], end='\n\n')


print(a[1:], end='\n\n')
print(a[1:, 0:2], end='\n\n')


b = a
print(b, end='\n\n')


# 출력 결과

[1 2 3 4 5] <class 'numpy.ndarray'>

2

[2 4]

[1 2 3]

[2 3 4 5]   [1 2 3]

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]] (3, 4)

[[ 5  6  7  8]
 [ 9 10 11 12]]

[1 2 3 4] 1 1 [[1 2 3 4]]

1

[[ 5  6  7  8]
 [ 9 10 11 12]]

[[ 5  6]
 [ 9 10]]

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

 

소스코드의 일부를 보시면 a[값1:값2] 로 작성되어있는 의미는 다음과 같습니다.

 

- 1차원 배열의 자료를 출력하고, 값1+1로 시작하여 값2의 범위까지 출력하는 것을 뜻합니다.

 

그 밑의 출력 문장을 보시면 a[값1:값2:값3] 으로 값3까지 있는 문장에서는 값3만큼 띄어넘어 출력하는 것을 뜻합니다.

 

- 여기서는 1:5 만 출력한다면 2 3 4 5가 출력되겠지만 값3에 2를 넣엇기때문에 2 4 가 출력됩니다.

 

shape 함수는 해당하는 배열이 몇행 몇열의 배열인지 출력해주는 함수입니다.

 

2차원 배열에서는 행과 열로 구성되고 있기 때문에 [값1:값2 , 값3,값4] 의 범위로 지정하게 됩니다.

 

a[값1 : ] 의 경우는 값1의 행부터 마지막 행까지 출력되는 것을 의미하게 됩니다.

 

Numpy 복사하기

 

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

b = a # 이건 주소치환
b[0][0] = 100
print(a)
print()
print(b)
print('**' * 10)
print()
c = np.copy(a) # 원본을 가지고 또 다른 배열주소 하나 만들어서 저장
c[0][0] = 200
print(a)
print('**'*10)
print(c)

a 배열을 만든후 주소 치환을 이용하여 b에 그대로 복사하여 동일하게 출력 된 것을 확인 할 수 있습니다.

 

그 다음 np.copy() 를 이용하여 c 에 2차원 배열 a를 다른 주소를 통하여 c에 복사하게 됩니다.

 

여기서 복사한 2차원 배열 c 의 값이 바뀌더라도 기존 a 배열에는 영향이 없습니다.

 

Numpy 의 서브Array

 

d=a[:2, 1:3]
print(a, end='\n\n') # 2   3 이 부분을 서브 array라고 한다
print(d, end='\n\n') # 6   7

print(a) 


# 출력 결과

[[100   2   3   4]
 [  5   6   7   8]
 [  9  10  11  12]]

[[2 3]
 [6 7]]

[[100   2   3   4]
 [  5   6   7   8]
 [  9  10  11  12]]

d 배열에 a 배열의 1 ~ 2행과 2 ~ 3 열의 값을 d 배열에 저장하였습니다.

 

그에따른 결과는 다음과 같으며 이것을 서브배열이라고 칭합니다. 이후 다시 a 배열을 출력해보면

 

기존 a 배열에는 영향이 없는 것을 알 수 있습니다.

 

그 외 추가 예제

 

a = np.array([[1,2,3,],[4,5,6],[7,8,9]])
r1 = a[1, :] 
print(r1)
print(r1, r1.shape)
print()

r2 = a[1:2, :]
print(r2, r2.shape)
print()


# 출력 결과

[4 5 6]
[4 5 6] (3,)

[[4 5 6]] (1, 3)

 

위에서 설명 드렸던 것처럼 .shape() 함수는 행렬의 차원을 개념으로 표현하는 것입니다.

 

여기서 r1 의 a[1, :] 는 a[1,] 과 동일한 의미로 해석 될 수 있습니다. 출력이 [4 5 6] 이지만 (3, )과 같이 출력 되는 이유는

1차원 배열 형태로 출력하였기 때문입니다.

 

그 차이를 비교하기 위해 r2 를 확인해보시면 쉽게 이해하실 수 있습니다. 

 

위에 설명을 보시면 2차원 배열의 경우 (값1 : 값2 , 값3 : 값4 ) 로 범위를 지정하여 이번에는 (1, 3) 과 같이 출력 된 것을 알 수 있습니다.

반응형
반응형

2020/05/28 - [python] - [python] Numpy

 

[python] Numpy

Numpy 란? C언어로 개발되었으며, 계산을 위한 라이브러리로서 다차원 배열을 처리하는데 필요한 기능을 제공합니다. Numpy 데이터 타입 # numpy : ndarray import numpy as np nn = [1, 2, 3.5] nn1 = (6,7,8,9)..

lightchan.tistory.com

 

Numpy에서 zeros / ones / full / eye 함수 

 

import numpy as np

c = np.zeros((2, 2))
print(c, end = '\n\n')

d = np.ones((2,2))
print(d, end = '\n\n')
d = np.full((2,2 ), 10)
print(d, end = '\n\n')

e = np.eye(3) # 3행 3열짜리 단위행렬
print(e, end = '\n\n')


# 출력 결과

[[0. 0.]
 [0. 0.]]

[[1. 1.]
 [1. 1.]]

[[10 10]
 [10 10]]

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]

np.zeros((2,2)) 는 2 행 2 열 짜리 2차원 배열을 0 으로 초기화 하겠다는 의미입니다.

 

np.ones ((2,2)) 는 2행 2열 짜리 2차원 배열을 1로 초기값을 설정해주는 것입니다.

 

np.full ((2,2), 10) 의 경우는 2행 2열 짜리 2차원 배열을 10으로 초기화 하겠다는 의미입니다.

 

저 위치에 다른 정수를 넣을 경우 해당 정수로 초기화하며 출력합니다.

 

np.eye(3) 의 경우 단위 행렬을 만드는 함수로 안의 정수값에 해당하는 단위 행렬을 출력해줍니다. 여기서는 3,3ㄷ의 단위 행렬을 출력해줍니다.현재는 3단위 행렬이지만, np.eye(2)를 할 경우, 2x2 행렬이 만들어집니다.

 

 

Numpy 난수 값 얻기

np.random.seed(0) 

print(np.random.rand(3), end = '\n\n') 

print(np.random.randn(5), end = '\n\n')

print(np.random.randint(3, size=6), end = '\n\n')
print(np.random.randint(3, size=(3,4)), end = '\n\n')
print(np.random.randint(3, size=(3,4,5)), end = '\n\n')


print(list(range(3)), end = '\n\n')
print(np.arange(3), end = '\n\n')

f = {i:np.random.randn() for i in range(3)}
print(f, end = '\n\n')



# 출력 결과

[0.5488135  0.71518937 0.60276338]

[-2.2683282   1.33354538 -0.84272405  1.96992445  1.26611853]

[2 0 1 1 1 1]

[[0 1 0 0]
 [1 2 0 2]
 [0 1 1 2]]

[[[0 1 1 1 0]
  [2 0 2 2 0]
  [2 0 0 0 1]
  [1 2 0 0 1]]

 [[0 1 2 2 0]
  [1 1 1 1 2]
  [2 2 0 2 1]
  [0 1 2 0 0]]

 [[2 0 0 0 0]
  [0 0 2 0 2]
  [1 1 1 0 1]
  [1 1 0 1 2]]]

[0, 1, 2]

[0 1 2]

{0: -0.5058765397605117, 1: 0.42539339846964996, 2: -0.027971183469780222}

 

 

np.random.seed(0) 란 임의의 시드를 생성합니다. seed 안에 값을 넣으면 항상 같은 결과를 반환합니다

 

np.random.rand(3) 란 난수 발생 균등분포를 따르기 때문에 음수 값은 출력되지 않습니다.

 

np.dandom.randn(5) 란 표준 정규분포를 따르는 난수를 발생시킵니다. rand() 와는 다르게 음수도 출력합니다.

 

맨 처음 seed에 0을 넣줬기 때문에 현재는 반복하여 출력하여도 같은 결과만 출력하게 됩니다.

 

매 출력 다른 결과를 원하신다면 seed(0)에서 0을 빼시면 됩니다.

 

np.random.randint()는randint(정수값)의 범위 내에서 균일분포의 정수난수를 발생 시킵니다. 여기서

 

(np.random.randint(3, size=6) 는 0~2 사이의 정수난수를 발생기키고 size는 6개를 받도록 하였습니다.

 

np.random.randint(3, size=(3,4) 의 경우는 범위는 위와 동일하지만, size는 2행 3열의 2차원 배열을 출력합니다.

반응형
반응형

Numpy 란?

C언어로 개발되었으며, 계산을 위한 라이브러리로서 다차원 배열을 처리하는데 필요한 기능을 제공합니다.

 

 

Numpy 데이터 타입

# numpy : ndarray
import numpy as np

nn = [1, 2, 3.5]
nn1 = (6,7,8,9)
ss1 = ['tom', 'james', 'oscar']
ss2 = {'a' , 'b', 'c'}

print(nn, ' ', type(nn))
print(nn1, ' ' , type(nn1))
print(ss1, ' ' , type(ss1))
print(ss2, ' ' , type(ss2))

# 출력 결과

[1, 2, 3.5]   <class 'list'>
(6, 7, 8, 9)   <class 'tuple'>
['tom', 'james', 'oscar']   <class 'list'>
{'a', 'b', 'c'}   <class 'set'>

 

변수에 할당한 데이터와 출력 된 값 및 데이터 타입 형태를 보면 들어간 타입의 형태로 출력 되는 것을 알 수 있스니다.

 

서로 성격이 다른 타입일 경우 상위 타입을 따라서 출력됩니다.

 

- 바깥쪽이 가장 큰 상위 타입

str ( somplex ( float ( int ) ) )

 

Numpy 메모리 저장

 

파이썬과 Numpy가 차지하는 메모리에는 차이가 있다.

 

파이썬은 값에 상관없이 다 다른 메모리를 차지하는 특징이있습니다.

li = list(range(1,10))
print(li) # list 형태

print(id(li[0]), id(li[1]), id(li[2]), id(li[3]), id(li[4]), id(li[5]), id(li[6]), id(li[7]), id(li[8]))


# 출력 결과

[1, 2, 3, 4, 5, 6, 7, 8, 9]
10914496 10914528 10914560 10914592 10914624 10914656 10914688 10914720 10914752

 

출력 결과를 보시면 id 값이 전부 다른 것을 확인 할 수 있습니다.

 

반면, Numpy 의 경우 C의 배열을 사용하기 때문에 하나의 메모리 안에 데이터를 하나씩 쌓아두는 특징을 가지고 있습

니다.

 

 

numpy_arr = np.array(li)

print(id(numpy_arr[0]), id(numpy_arr[1]), id(numpy_arr[2]), id(numpy_arr[3]), id(numpy_arr[4]))


# 출력 결과

139921874137520 139921874137520 139921874137520 139921874137520 139921874137520

출력 되는 id의 값이 전부 동일한 것을 확인할 수 있습니다.

 

 

결과적으로, 데이터 분석을 할 경우 들어오는 데이터의 양이 많기 떄문에 python 의 list 를 사용하는 것이 아니라

 

Numpy의 array 배열을 사용하는 것이 더 적합한 것을 알 수 있습니다.

 

 

추가 - 위에 특징들로인해 python의 list 값에 *값 을 해주면 list를 값 만큼 반복하지만 Numpy 의 경우 각 요소들에 * 값

 

을 해주는 특징을 가집니다.

print('a ' * 10)

for i in li:
  print(i*10, end = ' ')
  

# 출력 결과

a a a a a a a a a a 
10 20 30 40 50 60 70 80 90 

 

Numpy 배열

넘파이에서 사용하는 배열은 주로 벡터와 행렬을 사용하는 선형대수 계산에 사용됩니다.

 

1차원 배열 - 리스트를 넣으면 배열로 변환

exarr = np.array([1,2,3,4,5,6,7,8,9])


# 출력 결과

[1 2 3 4 5 6 7 8 9]   <class 'numpy.ndarray'>

 

2차원 배열 - 리스트의 리스트(list of list)를 이용하는 경우 2차원 배열을 생성할 수 있습니다. 가로는 행의 개수 세로는 열의 개수가 됩니다.

 

exarr1 = np.array([[1,2,3,4],[5,6,7,8]])
print(exarr1, ' ' , type(exarr1))


# 출력 결과

[[1 2 3 4]
 [5 6 7 8]]   <class 'numpy.ndarray'>

Numpy 에서의 배열은 다른 배열과는 다른 차이점을 가지고 있습니다.

 

예를들어 아래 소스에서도 보여드리겠지만, arr[0] 과 arr[[0]] dms 다른 점을 가지고 있습니다.

 

arr[0] 은 1차원 배열 , arr[[0]] 은 2차원 배열이라는 특징을 가지고 있습니다.

 

import numpy as np

arr1 = np.array([[10,20,30], [40,50,60]], dtype='float32')
print(type(arr1), ' ' , arr1.dtype, ' ' , arr1.shape, ' ' , arr1.ndim, ' ' , arr1.size, end = '\n')

print(arr1, end = '\n\n')

print(arr1[0,0], arr1[0, 1], end = '\n\n')
arr1[0] = 10
print(arr1[0,1], arr1[0,2], end = '\n\n')

print('-------------------------')

print(arr1, end = '\n\n')

print(arr1[[0]], end = '\n\n')

print(arr1[[0,1]], end = '\n\n')

print(arr1[0], end = '\n\n')


# 출력결과

<class 'numpy.ndarray'>   float32   (2, 3)   2   6
[[10. 20. 30.]
 [40. 50. 60.]]

10.0 20.0

10.0 10.0

-------------------------

[[10. 10. 10.]
 [40. 50. 60.]]

[[10. 10. 10.]]

[[10. 10. 10.]
 [40. 50. 60.]]

[10. 10. 10.]

 

 

 

위에 소스를 보시면 arr1[0]은 1차원 배열로 list 형태인 것을 알 수 있으며,

 

그 다음 줄 arr1[[0]] 인 경우는 arr1[0]과 다르게 0 행 1열의 2차원 배열을 의미하며 [[10. 10. 10]] 을 출력하였습니다.

 

 

반응형

+ Recent posts