# numpy.median 사용 / 슬라이싱, del 사용
import numpy as np

# 찾고자 하는 숫자가 있는 리스트 생성
a = [1,7,11,12,14,23,33,47,51,64,67,77,139,672,871]

# 리스트야! 내 숫자 담고 있늬? / binary함수야! 얼마나 빨리 찾길래 내가 널 손수 만들어야하늬?
def binary(list_data,find_num,count=0) :
    if np.median(list_data) < find_num : # 47 < 67
        count += 1
        del list_data[:list_data.index(np.median(list_data))+1]
    elif np.median(list_data) > find_num :
        count += 1
        del list_data[list_data.index(np.median(list_data)):]
    elif np.median(list_data) == find_num :
        return count, list_data
    else :
        return "없다 이놈아"
    return binary(list_data,find_num,count)
        
binary(a,67)


##########################################################################################

# 원래의 데이터 손상없는 ver.
import numpy as np

a = [1,7,11,12,14,23,33,47,51,64,67,77,139,672,871]

# 리스트야! 내 숫자 담고 있늬? / binary함수야! 얼마나 빨리 찾길래 내가 널 손수 만들어야하늬?
def binary(data,find_num,count=0) :
    list_data = list(data)
    median = np.median(list_data)
    if median < find_num :
        count += 1
        del list_data[:list_data.index(median)+1]
    elif median > find_num :
        count += 1
        del list_data[list_data.index(median):]
    elif median == find_num :
        count += 1
        return ("%d은(는) 이진탐색 %d번 만에 찾았습니다"%(find_num,count))
    else :
        return "없다 이놈아"
    return binary(list_data,find_num,count)
        
print(binary(a,67))
print(a) # a는 데이터에 대해서는 훼손되지 않았음

 

 

 

 

 

 

 

 

합성곱 이해를 위한 이미지

 

 

 

위의 이미지에서 맨 마지막 연산이 15가 되도록 하는 파이썬 코드

1
2
3
4
5
6
import numpy as np
        
= np.array([[1,2,3,],[0,1,2],[3,0,1]])
filter = np.array([[2,0,1],[0,1,2],[1,0,2]])
 
print(np.sum(x*filter)) # 15
cs

 

 


 

covolution 과정을 이해하기 위한 빌드업 문제와 코드

 

문제 1.

1
2
3
= np.array([[1,2,3,0],[0,1,2,3],[3,0,1,2],[2,3,0,1]])
 
print(a[0:3,0:3])
cs

 

 

문제 2.

1
print(a[0:3,1:4])
cs

 

 

문제 3.

1
print(a[1:4,0:3])
cs

 

 

문제 4.

1
print(a[1:,1:])
cs

 

 

 


 

 

 

import numpy as np

# data array인 a와 filter array인 filter를 생성한다.
a = np.array([[1,2,3,0],[0,1,2,3],[3,0,1,2],[2,3,0,1]])
filter = np.array([2,0,1,1]).reshape(2,2)

# matrix_convolution 함수
def matrix_convolution (data,filter_data,stride) :
	# stirde * (filter_data[열] or filter_data[행])이 data의 열, 혹은 행보다 크면 안됨
    if stride*filter_data.shape[0] > data.shape[0] or stride*filter_data.shape[1] > data.shape[1] :
        return 'stride가 너무 큽니다.'
        
    # 결과 리스트 생성, 결과를 담을 행렬의 shape을 위해서 count_i, count_j 만듦
    result = []
    count_i = 0
    count_j = 0
    
    # convolution 코드
    for i in range(0,data.shape[0]-filter_data.shape[0]+1,stride) :
        count_i += 1
        for j in range(0,data.shape[1]-filter_data.shape[1]+1,stride) :
            count_j += 1
            result.append(np.sum(data[i:filter_data.shape[0]+i,j:filter_data.shape[1]+j]*filter_data))
	
    # 결과 list를 count_i와 count_j를 이용하여 배열로 생성
    result = np.array(result).reshape(int(count_j/count_i),count_i)
    return result

matrix_convolution(a,filter,2)

 

 

 

 

 

 

 

나보다 돈 많이 벌고 잘 사는 사람이 예쁘게 잘 만든 numpy 모듈을 굳이 굳이 for문으로 만들어 보자.

numpy를 for문으로 구현하기 위해서는 디지털 논리회로로 생각하면 쉽다.

 


 

예를 들어 행렬이 아래와 같이 있고, 행렬곱을 한다고 하면 다음과 같다.

 

                1 2             2 3          (1*2 + 2*1) (1*3 + 2*4)

                3 4             1 4          (3*2 + 4*1) (3*3 + 4*4)

 

 

 

위의 행렬곱을 요소로 생각하면 다음과 같다.

 

                00 01          00 01      (00*00+01*10) (00*01+01*11)

                10 11          10 11      (10*00+11*10) (10*01+11*11)

 

 

 

요소를 활용해 행렬곱을 나타낸 식을 세로로 세우면 다음과 같다.

                                                          a[0]    a[1]   b[0]   b[1]       실제 위치

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

                00*00                                   0        0       0       0

+              01*10                                   0        1       1       0

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

                00*01                                   0        0       0       1

+              01*11                                   0        1       1       1

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

                10*00                                   1        0       0       0

+              11*10                                   1        1       1       0

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

                10*01                                   1        0       0       1

+              11*11                                   1        1       1       1

 

 

 

[0]은     00001111

[1][2]는  01010101

[3]은     00110011 로 위치가 변한다.

 

따라서 for문을 3개 중첩할 때

for i :

    for j :

        for k :

 

[0]에는 [i]를 / [1][2]에는 [k]를 / [3]에는 [j]를 넣으면 된다.

a[0][1] * b[2][3]

a[ i][k] * b[k][ j]

 


 

곱행렬을 넣을 행렬을 선언하기 위해서 알아야 하는 기본적인 개념은

행렬 (2*4) 와 (4*2) 의 행렬 곱은 (2*2) 가 나온다는 것이다.

즉, 첫번째 행렬의 행과 두번째 행렬의 열로 행렬이 구성된다.

행렬 (i*j) 와 (n*m) 의 행렬 곱은 (i*m) 로 나온다.

 

따라서 np_dot이라는 빈 array, 혹은 list를 구현할 때 a[0]의 크기와 b[1]의 크기로 np_dot을 생성한다.

 

 


 

 

# 행렬곱만 list로 구현
import numpy as np
def np_dot(a,b) :                                  # 행렬곱함수
    np_dot= np.zeros((a.shape[0],b.shape[-1]))     # np_dot이라는 곱행렬을 담을 빈 행렬 만듦
    for i in range(len(a)) :							
        for j in range(a.shape[0]) :               # 행렬의 shape은 (n,n)임을 참고
            for k in range(a.shape[1]) :
                np_dot[i][j] += a[i][k]*b[k][j]    # 디지털 논리회로 참고
    return np_dot

print(np_dot(a,b))


# ------------------------------------------------------------------------------------------------


# list로 행렬곱 구하기
def np_dot(a,b) :
    a_shape = [len(a),len(a[0])]
    b_shape = [len(b),len(b[0])]
    
    # np_dot 생성
    np_dot = []
    for i in range(a_shape[0]) :
        np_dot.append([0]*b_shape[-1])
       
    # 행렬곱 수행
    for i in range(len(a)) :
        for j in range(a_shape[0]) :
            for k in range(a_shape[1]) :
                np_dot[i][j] += a[i][k]*b[k][j]
    return np_dot

# 세로 출력
for i in np_dot(a,b) :
    print(i)
    
 # 가로 출력
print(np_dot(a,b))

 

 

 

 

'코딩 > 문제' 카테고리의 다른 글

문제6. (파이썬) 합병정렬  (0) 2020.06.05
문제5. (파이썬) 삽입정렬  (0) 2020.06.04
문제4. (파이썬) 버블정렬  (0) 2020.06.03
문제3. (파이썬) 이진탐색  (0) 2020.06.02
문제2. (파이썬) matrix_convolution 구현  (0) 2020.06.01

+ Recent posts