Sunday, November 29, 2015

복사와 뷰(Copies and Views)

배열을 조작할 때, 배열의 데이터가 새로운 배열로 복사되는 경우도 있지만 그렇지 않은 경우가 있다.

1. 복사되지 않는 경우(단순 할당)
배열 객체나 데이터가 복사되지 않고 단순하게 할당된다.

코드
arr1 = np.arange(12)
print("arr1 : %s" %arr1)
print("arr1의 형태 : %s" %arr1.shape)
arr2 = arr1 
print(arr2 is arr1)
arr2.shape= 3,4
print("arr2의 형태를 바꾼 후, arr1의 형태 : {0} ".format(arr1.shape))
새로운 객체는 생성되지 않고, 같은 ndarray 객체는 두 개의 이름을 가진다.(arr1, arr2)

결과
arr1 : [ 0  1  2  3  4  5  6  7  8  9 10 11]
arr1의 형태 : 12
True
arr2의 형태를 바꾼 후, arr1의 형태 : (3, 4) 


2. 뷰 혹은 얕은 복사(Shallow copy)
서로 다른 배열 객체가 같은 데이터를 공유할 수 있다. view 함수는 같은 데이터를 바라보는 새로운 배열 객체를 생성한다.

코드
view1 = arr1.view()
print("view1 : ")
print(view1)
print("view1은 arr1과 서로 다른 배열 객체이다 :  그러므로 {0} " .format(view1 is arr1))
print("view1은 arr1의 데이터의 뷰이므로 데이터를 공유한다 : 그러므로 {0}" .format(view1.base is arr1))
view1.shape = 2,6
print("view1 : ")
print(view1)
print("view1의 형태를 바꾼 후, arr1의 형태 : {0} " .format(arr1.shape))
view1[1,2] = 1234
print("view1의 데이터를 바꾼 후, arr1 : ")
print(arr1)

결과
view1 : 
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
view1은 arr1과 서로 다른 배열 객체이다 :  그러므로 False 
view1은 arr1의 데이터의 뷰이므로 데이터를 공유한다 : 그러므로 True
view1 : 
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]]
view1의 형태를 바꾼 후, arr1의 형태 : (3, 4) 
view1의 데이터를 바꾼 후, arr1 : 
[[   0    1    2    3    4    5]
 [   6    7 1234    9   10   11]]


3. 깊은 복사(Deep copy)
copy함수는 배열과 데이터의 완전한 카피를 생성한다.

코드
dc = arr1.copy()
print("dc : ")
print(dc)
print("dc는 arr1과 서로 다른 배열 객체이다 :  그러므로 {0} " .format(dc is arr1))
print("dc는 arr1과 어떤것도 공유하지 않는다. : 그러므로 {0}" .format(dc.base is arr1))
dc[0,0] = 9999
print("dc의 데이터를 바꾼 후, arr1 : ")
print(arr1)

결과
dc : 
[[   0    1    2    3]
 [   4    5    6    7]
 [1234    9   10   11]]
dc는 arr1과 서로 다른 배열 객체이다 :  그러므로 False 
dc는 arr1과 어떤것도 공유하지 않는다. : 그러므로 False
dc의 데이터를 바꾼 후, arr1 : 
[[   0    1    2    3]
 [   4    5    6    7]
 [1234    9   10   11]]

Tuesday, November 17, 2015

numpy 모듈의 배열 생성과 출력

배열 생성하기
코드
import numpy as np

# array 함수를 사용하는 일반 python 리스트나 튜플을 이용
a = np.array([2,3,4])
print("배열 a = %s" %a)
print("배열 a의 각 요소의 데이터형 : %s " %a.dtype)
b = np.array([2.3, 3.3, 4.4])
print("배열 b = %s" %b)
print("배열 b의 각 요소의 데이터형 : %s " %b.dtype)
c = np.array([(1.5, 2, 3), (4, 5, 6)])
print("배열 C는 2차원 배열 : ")
print(c)

결과
배열 a = [2 3 4]
배열 a의 각 요소의 데이터형 : int32 
배열 b = [ 2.3  3.3  4.4]
배열 b의 각 요소의 데이터형 : float64 
배열 C는 2차원 배열 : 
[[ 1.5  2.   3. ]
 [ 4.   5.   6. ]]


배열을 생성할 때, 요소들은 모르고 크기만 지정하고 싶은 경우
코드
print("0으로 가득찬 배열 만들기")
print(np.zeros((3,4)))
print("1으로 가득찬 배열 만들기")
print(np.ones((2,5)))
print("랜덤값을 가지는 배열 만들기")
print(np.random.random((2,2)))

결과
0으로 가득찬 배열 만들기
[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]
1으로 가득찬 배열 만들기
[[ 1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.]]
랜덤값을 가지는 배열 만들기
[[ 0.85682065  0.46422514]
 [ 0.00486033  0.48674269]]


arange함수를 이용해서 좀 더 간단히 배열 만들기
코드
print("0부터 10개")
print(np.arange(10))
print("3부터 10-1까지의 숫자를 2 간격으로")
print(np.arange(3,10,2))

결과
0부터 10개
[0 1 2 3 4 5 6 7 8 9]
3부터 10-1까지의 숫자를 2 간격으로
[3 5 7 9]


arange함수는 간격을 계산해서 입력해줘야 하는 단점이 있으므로 그럴 때에는 linspace 함수를 사용한다.
코드
print("0부터 2사이의 숫자를 9개")
print(np.linspace(0, 2, 9))

결과
0부터 2사이의 숫자를 9개
[ 0.    0.25  0.5   0.75  1.    1.25  1.5   1.75  2.  ]


다차원 배열과 모양
코드
print("1차원 배열 ")
array1 = np.arange(6)
print(array1)

print("2차원 배열(4행 3열)")
array2 = np.arange(12).reshape(4,3)
print(array2)

print("3차원 배열(높이가 3인 2행 4열 배열 = 2행 4열 배열 3개)")
array3 = np.arange(24).reshape(3, 2, 4)
print(array3)

print("만약 배열의 크기가 너무 커서, 다 표시될 수 없으면 자동으로 배열의 중간 값들을 생략한다.")
print(np.arange(10000).reshape(100,100))

결과
1차원 배열 
[0 1 2 3 4 5]
2차원 배열(4행 3열)
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
3차원 배열(높이가 3인 2행 4열 배열 = 2행 4열 배열 3개)
[[[ 0  1  2  3]
  [ 4  5  6  7]]

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

 [[16 17 18 19]
  [20 21 22 23]]]
만약 배열의 크기가 너무 커서, 다 표시될 수 없으면 자동으로 배열의 중간 값들을 생략한다.
[[   0    1    2 ...,   97   98   99]
 [ 100  101  102 ...,  197  198  199]
 [ 200  201  202 ...,  297  298  299]
 ..., 
 [9700 9701 9702 ..., 9797 9798 9799]
 [9800 9801 9802 ..., 9897 9898 9899]
 [9900 9901 9902 ..., 9997 9998 9999]]

Sunday, November 15, 2015

numpy모듈의 기본 연산

배열을 가지고 기본적인 산술 연산을 할 수 있다.

코드
a = np.array([20, 30, 40, 50])
print("배열 a : %s" %a)
b = np.arange(4)
print("배열 b : %s"  %b)
print("배열 a - b : %s" %(a-b))
print("배열의 각 요소 제곱 값 구하기 : %s" %b**2)
print("비교 연산으로 참 거짓 값 구하기 : %s" %(a<30))

결과
배열 a : [20 30 40 50]
배열 b : [0 1 2 3]
배열 a - b : [20 29 38 47]
배열의 각 요소 제곱 값 구하기 : [0 1 4 9]
비교 연산으로 참 거짓 값 구하기 : [ True False False False]


각 요소에 대한 곱 연산은 * 을 이용하지만, 행렬 곱은 dot 함수를 이용한다.

코드
array1 = np.array([[1, 1], [0, 1]])
array2 = np.array([[2, 3], [1, 5]])
print("배열 array1 : ")
print(array1)
print("배열 array2 : ")
print(array2)
print("배열의 각 요소들의 단순 곱 : ")
print(array1*array2)
print("행렬 곱 구하기 : ")
print(array1.dot(array2))
print(np.dot(array1, array2))

결과
배열 array1 : 
[[1 1]
 [0 1]]
배열 array2 : 
[[2 3]
 [1 5]]
배열의 각 요소들의 단순 곱 : 
[[2 3]
 [0 5]]
행렬 곱 구하기 : 
[[3 8]
 [1 5]]
[[3 8]
 [1 5]]


일부 연산, +=, *= 등은 새로운 배열을 생성하지 않고 이미 존재하고 있는 배열을 수정한다.

코드
A = np.ones((2,3), dtype=int)
B = np.random.random((2,3))
print(" 배열 A : ")
print(A)
print(" 배열 B : ")
print(B)
print(" 배열 A의 각 요소에 3 곱하기(결과가 A에 저장된다) -> 현재 배열 A :  ")
A *= 3
print(A)
print(" 배열 B의 각 요소에 배열 A의 각 요소의 값을 더한다.(결과가 B에 저장된다) -> 현재 배열 B : ")
B += A
print(B)

결과
배열 A : 
[[1 1 1]
 [1 1 1]]
 배열 B : 
[[ 0.96996427  0.86763816  0.32974234]
 [ 0.68707904  0.2039358   0.88133135]]
 배열 A의 각 요소에 3 곱하기(결과가 A에 저장된다) -> 현재 배열 A :  
[[3 3 3]
 [3 3 3]]
 배열 B의 각 요소에 배열 A의 각 요소의 값을 더한다.(결과가 B에 저장된다) -> 현재 배열 B : 
[[ 3.96996427  3.86763816  3.32974234]
 [ 3.68707904  3.2039358   3.88133135]]


배열의 모든 요소의 합 계산과 같은 많은 단항 연산 또한 간단히 계산된다.

코드
a = np.arange(12).reshape(4,3)
print("배열 a : ")
print(a)
print("배열의 각 요소의 합 : ")
print(a.sum())
print("배열의 요소중 가장 작은 값을 가지는 요소 : ")
print(a.min())
print("배열의 요소중 가장 큰 값을 가지는 요소 : ")
print(a.max())

결과
배열 a : 
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
배열의 각 요소의 합 : 
66
배열의 요소중 가장 작은 값을 가지는 요소 : 
0
배열의 요소중 가장 큰 값을 가지는 요소 : 
11


기본적으로, 위의 연산들은 배열의 모양에 관계없이 단순히 숫자로 이루어진 리스트로써 생각될 수 있다. 그러나 axis 파라미터를 적용함으로써 다차원 배열의 특정한 축을 기준으로 계산하는 것 또한 가능하다.

코드
a = np.arange(12).reshape(4,3)
print("배열 a : ")
print(a)
print("배열의 각 column의 합을 구하기")
print(a.sum(axis=0))
print("배열의 각 row의 합을 구하기")
print(a.sum(axis=1))
print("배열의 각 row의 누적합을 구하기")
print(a.cumsum(axis=1))

결과
배열 a : 
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
배열의 각 column의 합을 구하기
[18 22 26]
배열의 각 row의 합을 구하기
[ 3 12 21 30]
배열의 각 row의 누적합을 구하기
[[ 0  1  3]
 [ 3  7 12]
 [ 6 13 21]
 [ 9 19 30]]

Sunday, April 19, 2015

스프링(Spring)의 간단한 몇가지 내용

DI(Dependency Injection) 패턴
객체 사이의 의존 관계를 객제 자신이 아닌 외부의 조립기(컨테이너)가 수행하는 개념.
설정 파일이나 어노테이션을 이용해 관계 설정
Class A에서 B b = new B();  처럼 코드에 직접 명시하는 건 DI가 아님
-> 의존성을 낮추기 위해 인터페이스를 사용

객체간의 의존 관계는 생성자와 프로퍼티 설정의 2가지 방식이 존재
1. 생성자 방식
생성자의 매개변수를 통해 객체(bean)을 전달(주입)받는다.
xml상에서 <constructor-arg>태그 사용
빈 객체 <con....arg ref="....">
기본 데이터 타입 or string <con ~ arg value="....">
value는 string 타입으로 처리
<cons ~ arg><value type="long">2000</value></con~arg>

2. 프로퍼티 방식
setXXX() 형태의 설정 메소드를 통해서 필요한 객체와 값을 전달받는다. - XXX는 프로퍼티 이름
xml에서 <property name="프로퍼티 이름"> 으로 지정

3. xml의 네임스페이스를 이용한 프로퍼티 설정
<xmlns:p~~~>
<bean id="~~~~" p:ibatisDao-ref="dao">
ibatisDao 는 프로퍼티 이름, dao는 전달할 객체(bean)

Bean 객체 생성 및 사용
Bean생성 
<bean id="~~~~" class="~~~~~">
이 식별값을 getBean("id") 메소드를 이용하여 컨테이너로부터 객체를 가져와 사용
<bean> 태그의 factory-method 속성 값으로 static 메소드를 지정함으로써 빈을 생성하도록 설정 가능.

Bean의 라이프 사이클
<bean> 태그의 init-method 와 destory-method 속성을 설정함으로써 스프링 컨테이너가 Bean을 생성(종료)시 해당 메소드를 실행하게 한다.
initializing Bean 인터페이스 - afterPropertiesSet()
Spring 자체에서 제공하는 초기화 메소드
객체를 생성하고 프로퍼티를 초기화하고, 컨테이너 관련 설정을 완료한 뒤에 호출된다.
DisposableBean 인터페이스 - destroy()
빈 객체를 컨테이너에서 제거하기 전에 호출하여 빈 객체가 자원을 반납할 수 있도록 함.



AOP(Aspect Oriented Object) 지원 - 관점 지향 
해당 소스가 핵심 기능을 담당하는 코드인지, 공통적인 기능을 담당하는지 구분하는 것.

용어
advice -> 공통기능을 구현한 것(class)
target -> advice가 적용될 객체
joinpoint -> advice가 적용된 지점(target의 메소드)
pointcut -> 실제로 advice가 적용된 joinpoint
advisor(=aspect) -> advice + pointcut
weaving -> advice를 핵심 로직 코드에 적용하는 것.

스프링에서의 구현 방법
1. 스프링 API
2. POJO클래스(Plain Old Java Object)
3. AspectJ5에서 정의한 @Aspect 어노테이션 기반의 AOP 구현.

Monday, March 16, 2015

자바스크립트의 고계함수(higher-order function)

자바스크립트에서의 함수 이용 방법

higher-order function(고계함수)
functional programming(함수형 프로그래밍)으로부터 온 개념으로써, 인자나 반환값으로 함수를 사용하는 함수를 의미한다. 다음의 두가지 규칙을 가진다.
  * 인풋으로써 한개나 그 이상의 함수를 취한다.
  * 함수를 출력한다.

고계함수가 아닌 것은 first-class function(제 일급 함수)이라고 부른다. 이것은 함수를 객체로 취급할 수 있는 프로그래밍 언어의 성질 또는 그러한 함수를 의미한다.


결과는 63(위키피디아 발췌)

뉴라이트의 기본적인 개념과 특징

뉴라이트  한국에서 자칭 신우익을 이르는 말. 영어의 신(new) + 우익(right)의 합성어이다.  옛날 종북주의자 시절의 파시즘과 전체주의적 사상을 간직한 채 친일반민족 행위 옹호로 돌아선 사람들이다.  우파를 가장한 짝퉁 우파...