• numpy_pandas
  • 데이터 분석 & 시각화(numpy, pandas,matplotlib, seaborrn, streamlit)
  • 데이터 수집 (scraping, crawling)

''' Numpy 학습목표 : 수학과 통계에 관련된 함수를 지원하는 lib

  • 배열 데이터 타입 (인공지능 사용되는 데이터타입) : 모든 요소가 같은 자료형, 요소의 갯수를 바꿀 수 없다.
  • 행렬 연산
  • 배열의 차원, 크기, 타입
  • 배열 생성 함수 : array(), arange(), reshape() '''
In [2]:
import numpy as np
import pandas as pd
In [3]:
lst = [1,2,3,4,5]
print('type - ', type(lst))
type -  <class 'list'>
In [9]:
ary = np.array(lst)
print('type  - ', type(ary))
print('shape - ', ary.shape)
print('dim   - ', ary.ndim)
print('dtype - ', ary.dtype)
type  -  <class 'numpy.ndarray'>
shape -  (5,)
dim   -  1
dtype -  int64
In [10]:
def aryInfo(ary) :
    print('type  - ', type(ary))
    print('shape - ', ary.shape)
    print('dim   - ', ary.ndim)
    print('dtype - ', ary.dtype)
    print()
    print('data - ')
    print(ary)
In [11]:
aryInfo(ary)
type  -  <class 'numpy.ndarray'>
shape -  (5,)
dim   -  1
dtype -  int64

data - 
[1 2 3 4 5]
  • 벡터화 연산 : 배열의 각 요소에 대해서 반복연산을 하나의 명령어로 처리하는 것
  • 비교연산과 논리연산을 포함
In [15]:
lst = [1,2,3,4,5]
# error
# print(lst ** 2) 
result = []
for element in lst :
    result.append(element ** 2)
print(result)
[1, 4, 9, 16, 25]
In [16]:
ary = np.array(lst)
print(ary ** 2)
[ 1  4  9 16 25]
In [387]:
xAry = np.array([1,2,3])
yAry = np.array([3,2,1])

print('산술연산 - ', xAry + yAry)
print('비교연산 - ', xAry == 2)
print('비교연산 - ', xAry > 2)
print('비교연산 - ', (xAry == 2) & (yAry > 2))
print('인덱싱   - ', xAry[0])
print('슬라이싱 - ', xAry[0:2])

x = np.arange(10)
print(x)
산술연산 -  [4 4 4]
비교연산 -  [False  True False]
비교연산 -  [False False  True]
비교연산 -  [False False False]
인덱싱   -  1
슬라이싱 -  [1 2]
[0 1 2 3 4 5 6 7 8 9]
  • 2차원 배열(행렬, matrix) : list of list
In [43]:
print(' 2 * 3 배열을 생성하고 싶다면 - ')
lst = [[1,2,3],[4,5,6]]
for rIdx, row in enumerate(lst) :
    for cIdx , col in enumerate(row) :
        # print(rIdx, end='\t')
        # print(cIdx, end='\t')
        print(lst[rIdx][cIdx], end='\t')
    print()
 2 * 3 배열을 생성하고 싶다면 - 
1	2	3	
4	5	6	
In [47]:
twoAry = np.array(lst)
aryInfo(twoAry)
print()
print('len - ', len(twoAry)) # 행의 길이
print('len - ', len(twoAry[0])) # 열의 길이
print('len - ', len(twoAry[1]))
type  -  <class 'numpy.ndarray'>
shape -  (2, 3)
dim   -  2
dtype -  int64

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

len -  2
len -  3
len -  3
In [390]:
lst = [ [[1,2,3],[4,5,6]], [[1,2,3],[4,5,6]] ]
ary = np.array(lst, dtype=object)
aryInfo(ary)


# print(lst * 2)
type  -  <class 'numpy.ndarray'>
shape -  (2, 2, 3)
dim   -  3
dtype -  object

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

 [[1 2 3]
  [4 5 6]]]
[[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]]
  • 요소의 타입을 변경할 때 (astype())
In [55]:
aryInfo(ary.astype(np.int32))
type  -  <class 'numpy.ndarray'>
shape -  (2, 2, 3)
dim   -  3
dtype -  int32

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

 [[1 2 3]
  [4 5 6]]]
  • fancy indexing - 정수 인덱싱, 불리언 인덱싱
In [71]:
ary = np.array([0,1,2,3,4,5,6,7,8,9])
print('2의 배수인것들만 출력한다면? - ')

# for i in range(len(ary)):
#     if ary[i] % 2 ==0:
#         print(ary[i])

print(ary%2==0)
print('boolean indexing - ', ary[ary%2==0])

evenIdx = np.array([0,2,4,6,8])
print(ary[evenIdx])
2의 배수인것들만 출력한다면? - 
[ True False  True False  True False  True False  True False]
boolean indexing -  [0 2 4 6 8]
[0 2 4 6 8]
In [80]:
# Quiz
# 3의 배수만 출력
# 4로 나누어 1이 남는 값들만 출력
# 3의 배수이고 4로 나누어 1이 남는 값들만 출력

ary = np.arange(1,21)
aryInfo(ary)
print()
print(ary[ary%3==0])
print(ary[ary%4==1])
print(ary[(ary%3==0) & (ary%4==1)])
type  -  <class 'numpy.ndarray'>
shape -  (20,)
dim   -  1
dtype -  int64

data - 
[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20]

[ 3  6  9 12 15 18]
[ 1  5  9 13 17]
[9]
  • reshape() : 배열의 변형
In [91]:
ary = np.arange(1, 13).reshape(3,4)
aryInfo(ary)
type  -  <class 'numpy.ndarray'>
shape -  (3, 4)
dim   -  2
dtype -  int64

data - 
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
In [116]:
# Quiz
# 정수배열인덱싱을 이용해서 모든행의 0, 3 열의 값을 출력한다면
print(ary[:,[0,3]])
print()
# print(ary[0][0], ary[0,0])
# print(ary[:][0]) # 행의 값
# print(ary[:,0]) # 열의 값
# print()
# 불리언 인덱싱
print(ary[:,[True,False,False,True]])
[[ 1  4]
 [ 5  8]
 [ 9 12]]

[[ 1  4]
 [ 5  8]
 [ 9 12]]
In [117]:
print('5 - ',ary[1,0], type(ary[1,0]))
5 -  5 <class 'numpy.int64'>
In [124]:
# Quiz
# [2 10] 값을 추출 -
print('[2 10] - ', ary[[0,2],1], type(ary[[0,2],1]))
[2 10] -  [ 2 10] <class 'numpy.ndarray'>
In [157]:
# Quiz
# [[1 3] 
#  [9 11]] 값 추출 -

print(ary[[0,2]][:,[0,2]])
[[ 1  3]
 [ 9 11]]
In [158]:
ary = np.arange(1,7).reshape(2,3)
aryInfo(ary)
print()
transposeAry = ary.T
aryInfo(transposeAry)
type  -  <class 'numpy.ndarray'>
shape -  (2, 3)
dim   -  2
dtype -  int64

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

type  -  <class 'numpy.ndarray'>
shape -  (3, 2)
dim   -  2
dtype -  int64

data - 
[[1 4]
 [2 5]
 [3 6]]
In [166]:
print('1차원 배열에 대한 전치행렬이 필요할까요? - 필요함')
print('왜? 함수의 인자로 전달할 때 타입이 맞아야 하므로')
ary = np.arange(1,7)
aryInfo(ary)
print()
transposeAry = ary.reshape(1,6).T
aryInfo(transposeAry)
1차원 배열에 대한 전치행렬이 필요할까요? - 필요함
왜? 함수의 인자로 전달할 때 타입이 맞아야 하므로
type  -  <class 'numpy.ndarray'>
shape -  (6,)
dim   -  1
dtype -  int64

data - 
[1 2 3 4 5 6]

type  -  <class 'numpy.ndarray'>
shape -  (6, 1)
dim   -  2
dtype -  int64

data - 
[[1]
 [2]
 [3]
 [4]
 [5]
 [6]]
  • 다차원 배열을 1차원으로 바꿀때
  • flatten()
In [167]:
aryInfo(transposeAry.flatten())
type  -  <class 'numpy.ndarray'>
shape -  (6,)
dim   -  1
dtype -  int64

data - 
[1 2 3 4 5 6]
  • 배열 연결
In [186]:
print('행의 갯수가 동일한 두개의 배열을 연결 - hstack()')
ary01 = np.ones((3,4))
ary02 = np.zeros((3,4))
print(np.hstack([ary01,ary02]))
행의 갯수가 동일한 두개의 배열을 연결 - hstack()
[[1. 1. 1. 1. 0. 0. 0. 0.]
 [1. 1. 1. 1. 0. 0. 0. 0.]
 [1. 1. 1. 1. 0. 0. 0. 0.]]
In [187]:
print('열의 갯수가 동일한 두개의 배열을 연결 - vstack()')
ary01 = np.ones((3,4))
ary02 = np.zeros((3,4))
print(np.vstack([ary01,ary02]))
열의 갯수가 동일한 두개의 배열을 연결 - vstack()
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
In [213]:
print('stack() - 축 axis = 0 | 1')
ary01 = np.ones((3,4))
ary02 = np.zeros((3,4))
aryInfo(np.stack([ary01,ary02], axis = 0))
stack() - 축 axis = 0 | 1
type  -  <class 'numpy.ndarray'>
shape -  (2, 3, 4)
dim   -  3
dtype -  float64

data - 
[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[0. 0. 0. 0.]
  [0. 0. 0. 0.]
  [0. 0. 0. 0.]]]
In [211]:
print('dstack - 행이나 열이 아닌 깊이(depth) 방향으로 배열을 합치는 것')
aryInfo(np.dstack([ary01,ary02]))
dstack - 행이나 열이 아닌 깊이(depth) 방향으로 배열을 합치는 것
type  -  <class 'numpy.ndarray'>
shape -  (3, 4, 2)
dim   -  3
dtype -  float64

data - 
[[[1. 0.]
  [1. 0.]
  [1. 0.]
  [1. 0.]]

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

 [[1. 0.]
  [1. 0.]
  [1. 0.]
  [1. 0.]]]
In [219]:
ary = np.arange(1,7).reshape(-1,3) # -1 = 행은 신경 X 열의 갯수를 맞춰서 맞춰달라
np.tile(ary, (3,3))
Out[219]:
array([[1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6]])
In [250]:
# Quiz
# np.function() 결과가 동일하도록 구현한다면?
# array([[   0.,    0.,    0.,    1.,    1.],
#        [   0.,    0.,    0.,    1.,    1.],
#        [   0.,    0.,    0.,    1.,    1.],
#        [  10.,   20.,   30.,   40.,   50.],
#        [  60.,   70.,   80.,   90.,  100.],
#        [ 110.,  120.,  130.,  140.,  150.],
#        [   0.,    0.,    0.,    1.,    1.],
#        [   0.,    0.,    0.,    1.,    1.],
#        [   0.,    0.,    0.,    1.,    1.],
#        [  10.,   20.,   30.,   40.,   50.],
#        [  60.,   70.,   80.,   90.,  100.],
#        [ 110.,  120.,  130.,  140.,  150.]])


ary01 = np.zeros((3,3))
ary02 = np.ones((3,2))
ary03 = np.arange(10,160,10).reshape(3,5)
ary04 = (np.hstack([ary01,ary02]))
ary05 = (np.vstack([ary04,ary03]))
#print(ary05)
print(np.tile(ary05, (2,1)))
[[  0.   0.   0.   1.   1.]
 [  0.   0.   0.   1.   1.]
 [  0.   0.   0.   1.   1.]
 [ 10.  20.  30.  40.  50.]
 [ 60.  70.  80.  90. 100.]
 [110. 120. 130. 140. 150.]
 [  0.   0.   0.   1.   1.]
 [  0.   0.   0.   1.   1.]
 [  0.   0.   0.   1.   1.]
 [ 10.  20.  30.  40.  50.]
 [ 60.  70.  80.  90. 100.]
 [110. 120. 130. 140. 150.]]
  • 데이터 삭제 : delete()
  • 기준 axis = 0 (행), 1 (열)
  • 만약, 기준을 정의하지 않으면 1차원변경 삭제
  • in-place : 원본에 반영되는 함수
In [254]:
ary = np.random.randint(0,10, (3,4))
print(ary)
[[0 4 8 8]
 [8 6 2 0]
 [8 1 7 5]]
In [259]:
np.delete(ary, 1, axis = 0)
newAry = np.delete(ary, 1)
print(newAry)
[0 8 8 8 6 2 0 8 1 7 5]
In [260]:
print(ary)
[[0 4 8 8]
 [8 6 2 0]
 [8 1 7 5]]
  • 통계함수(차원축소 함수 == dimension reduction)
  • argmin, argmax : 인덱스를 반환하는 함수
In [265]:
ary = np.array([1,2,3,4,5,6,7,8,9,10])
print(np.sum(ary), np.mean(ary), np.median(ary), np.var(ary), np.std(ary))
55 5.5 5.5 8.25 2.8722813232690143
In [267]:
# 분위수
print('quartile - ', np.percentile(ary, 0))
print('quartile - ', np.percentile(ary, 25))
print('quartile - ', np.percentile(ary, 50))
print('quartile - ', np.percentile(ary, 75))
print('quartile - ', np.percentile(ary, 100))
quartile -  1.0
quartile -  3.25
quartile -  5.5
quartile -  7.75
quartile -  10.0
In [289]:
print('argmin - ', ary[np.argmin(ary)])
print('argmax - ', ary[np.argmax(ary)])
print()
print('any - ', np.any([True, False, True])) # 하나라도 참이면 True
print('all - ', np.all([True, False, True])) # 전체가 같지 않으면 False
argmin -  1
argmax -  10

any -  True
all -  False
In [301]:
ary = np.arange(1,21).reshape(4, -1)
print(ary, type(ary))
aryInfo(ary)
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]] <class 'numpy.ndarray'>
type  -  <class 'numpy.ndarray'>
shape -  (4, 5)
dim   -  2
dtype -  int64

data - 
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]]
In [300]:
print('2차원 배열에서 차원축소함수를 적용한다면 - 축의 방향이 중요!! axis = 0 , 1')
print('sum - ', np.sum(ary))
print('sum - ', np.sum(ary, axis = 0))
print('sum - ', np.sum(ary, axis = 1))
2차원 배열에서 차원축소함수를 적용한다면 - 축의 방향이 중요!! axis = 0 , 1
sum -  210
sum -  [34 38 42 46 50]
sum -  [15 40 65 90]
In [305]:
print(np.hstack([ary, np.sum(ary, axis = 1).reshape(1,4).T]))
[[ 1  2  3  4  5 15]
 [ 6  7  8  9 10 40]
 [11 12 13 14 15 65]
 [16 17 18 19 20 90]]
In [333]:
ary = np.random.randint(0,1000000, (5,6))
print(ary)
[[326816 764776 245633 331187 837845 278962]
 [298898  93200 315971 654648  22809 622964]
 [213983 730979 540261  56986 382041 836560]
 [345458 722928  56775 945598 580785 412014]
 [881451 198859 286796 343397 308836 366741]]
In [363]:
# Quiz
# 전체의 최대값
print('max - \n', np.max(ary))
# 행 합
print('sum - \n', np.sum(ary, axis = 1))
# 행 합을 열로 추가
print(np.hstack([ary, np.sum(ary, axis = 1).reshape(5,1)]))
# 각 행의 최대값
print('max - \n', np.max(ary, axis = 1))
# 각 행의 최대값을 열로 추가
print('max - \n', np.hstack([ary, np.max(ary, axis = 1).reshape(5,1)]))
# 각 열의 평균을 행으로 추가
print('col mean - \n', np.vstack([ary, np.mean(ary, axis = 0).astype('int32').reshape(1,-1)]))
# 각 열의 최소값
print('col min - \n', np.min(ary, axis = 0))
max - 
 993611
sum - 
 [2355134 2759164 3753749 1562788 3120634]
[[ 272663  341040    8826  499369  730658  502578 2355134]
 [ 384805  210361  798350  733100   73382  559166 2759164]
 [ 159585  755671  420272  922974  566827  928420 3753749]
 [  41312   76008  593076   97690  220786  533916 1562788]
 [ 993611  309508   75527  847784  517204  377000 3120634]]
max - 
 [730658 798350 928420 593076 993611]
max - 
 [[272663 341040   8826 499369 730658 502578 730658]
 [384805 210361 798350 733100  73382 559166 798350]
 [159585 755671 420272 922974 566827 928420 928420]
 [ 41312  76008 593076  97690 220786 533916 593076]
 [993611 309508  75527 847784 517204 377000 993611]]
col mean - 
 [[272663 341040   8826 499369 730658 502578]
 [384805 210361 798350 733100  73382 559166]
 [159585 755671 420272 922974 566827 928420]
 [ 41312  76008 593076  97690 220786 533916]
 [993611 309508  75527 847784 517204 377000]
 [370395 338517 379210 620183 421771 580216]]
col min - 
 [ 41312  76008   8826  97690  73382 377000]
  • 정렬
  • np.sort() : 원본에 대한 변경 X(inplace = False)
  • ary.sort() : 원본에 대한 변경 O(inplace = True)
In [375]:
ary = np.arange(10)
print(ary)
print()
np.random.shuffle(ary)
print()
print(ary)
print()
print('np sort - ', np.sort(ary)[::-1]) # 원본에 대한 변경이 없다 변경한 데이터를 유지하려면 변수에 담아야햠
print(ary)
ary.sort() # 원본이 바뀜
print(ary)
[0 1 2 3 4 5 6 7 8 9]


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

np sort -  [9 8 7 6 5 4 3 2 1 0]
[8 2 0 7 3 6 5 4 9 1]
[0 1 2 3 4 5 6 7 8 9]
  • 행렬에 대한 정렬
  • axis = 0(열), 1(행)
  • 만약, 정렬된 인덱스를 필요로 한다면? np.argsort()
In [378]:
ary = np.random.randint(1,17,(4,4))
ary
Out[378]:
array([[13,  1,  8,  6],
       [ 1,  7, 12, 10],
       [ 7, 16,  9,  5],
       [ 3, 13,  4, 12]], dtype=int32)
In [380]:
print('열에 대한 정렬 - ')
print(np.sort(ary, axis = 0))
print()
print('행 대한 정렬 - ')
print(np.sort(ary, axis = 1))
열에 대한 정렬 - 
[[ 1  1  4  5]
 [ 3  7  8  6]
 [ 7 13  9 10]
 [13 16 12 12]]

행 대한 정렬 - 
[[ 1  6  8 13]
 [ 1  7 10 12]
 [ 5  7  9 16]
 [ 3  4 12 13]]
In [382]:
ary = np.array([4,3,5,7])
print(ary)
[4 3 5 7]
In [383]:
sortIdx = np.argsort(ary)
print(sortIdx)
[1 0 2 3]
In [384]:
print(ary[sortIdx])
print(ary[sortIdx][::-1])
[3 4 5 7]
[7 5 4 3]
In [385]:
ary = np.random.randint(1,17,(4,4))
print(ary)
[[ 4 11  1  3]
 [ 1 16  2 12]
 [16  1  4 12]
 [12  2 13 11]]
In [386]:
np.argsort(ary, axis = 0)
Out[386]:
array([[1, 2, 0, 0],
       [0, 3, 1, 3],
       [3, 0, 2, 1],
       [2, 1, 3, 2]])
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: