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

print type(array1), '\n', array1
print type(array2), '\n', array2

"""
Explanation: ndarray
numpy의 기본 자료구조로 vector와 matrix를 표현
End of explanation
"""


array3 = np.arange(1, 4)
print array3, type(array3)

"""
Explanation: arange 
range()와 동일하지만 list가 아닌 ndarray 반환
End of explanation
"""


# 0 ~ 10의 범위를 5등분
array4 = np.linspace(0, 10, 5)
print array4

"""
Explanation: linspace(start, end, n)
start, end를 n개의 균일한 간격으로 분할
End of explanation
"""


print np.zeros((3, 5))
print np.zeros(5)

"""
Explanation: np.zeros((x, y))
x, y 사이즈의 영행렬 반환(사이즈는 tuple로 전달)
 details: https://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html#numpy.zeros
End of explanation
"""


# (n1, n2, x, y): (x, y) 행렬(1) n2개 생성 후 그것을 다시 n1개 만큼 생성하여 반환(dimension 증가)
print np.ones((2, 3, 2, 3))
print np.ones(5)

"""
Explanation: np.ones((x, y))
x, y 사이즈의 행렬(1) 반환(사이즈는 tuple로 전달)
 details: https://docs.scipy.org/doc/numpy/reference/generated/numpy.ones.html
End of explanation
"""


# np.random.rand(n)
## Uniform Distribution으로부터 [0, 1) 실수 n개 출력
print np.random.rand(3)

# np.random.randn(n)
## Standard Normal Distribution으로부터 n개의 실수 출력
print np.random.randn(3)

"""
Explanation: random sub package
무작위에 관한 모든 기능 포함
 details: https://docs.scipy.org/doc/numpy/reference/routines.random.html
End of explanation
"""


a = np.random.rand()
print a

"""
Explanation: (): 초과, 미만
[]: 이상, 이하
End of explanation
"""


np.random.seed(0)
print np.random.rand()

np.random.seed(7)
print np.random.rand()

"""
Explanation: seed(n): n에 따른 랜덤값 생성규칙 지정
임의값을 계속 유지해야할 때 사용
End of explanation
"""


array1 = np.array([1, 2, 3, 4])
array2 = np.array([[1, 2], [3, 4], [5, 6]])

print array1[0]
print array1[1:-1]

print array2

# 1행 출력
print array2[0]
# 1행 2열 출력
print array2[0, 1]
# 2행부터 끝까지, 1열부터 2열까지
print array2[1:, :2]
# 전체 행, 2열
print array2[:, 1]
# 전체 행, 2열부터(범위)
print array2[:, 1:]

"""
Explanation: slicing: 리스트, 문자열과 동일
End of explanation
"""


# np.random.randint(x, y, n): [x, y)의 정수 n개 반환
array = np.random.randint(0, 20, 10)
print array, type(array)

# 짝수 선별
even_mask = (array % 2 == 0)
print array[even_mask]
print array[array % 2 == 0]

"""
Explanation: array masking
ndarray의 원소를 선택, 제거 또는 추출하는 방법
End of explanation
"""


array = np.arange(1, 6) * 5
print array

array2 = array ** 2
print array2
print array2 ** 0.5

array1 = np.arange(0, 20, 2) + 2
array2 = np.arange(1, 11)
print 'array1:', array1, 'array2:', array2
print '-'*100
print 'array1 - array2', array1 - array2
print 'array1 * array2', array1 * array2
print 'array1 * array1', array1 * array1

array1 = np.array([[1, 1], [1, 1]])
array2 = np.array([[2, 2], [2, 2]])

print array1 * array2  # 원소간 곱셈
print array1.dot(array2) # 행렬곱셈(내적)

"""
Explanation: operations
기본 연산은 벡터화되어 전체 원소에 적용(element-wise)
End of explanation
"""


array = np.random.randint(1, 10, size = (4,4))
print array

print np.all(array < 7)

print np.any(array % 7 == 0)

"""
Explanation: logical operator 
all(): 전부
any(): 아무거나
End of explanation
"""


array = np.array([[1, 2, 3], [7, 8, 9]])
print array
print array.ravel()

"""
Explanation: ravel: multi-dimensional array -> one-dimensional array
End of explanation
"""


array = np.arange(1, 11)
print array

array2 = array.reshape(2, 5)
print array2

# numpy methods for descriptive statistics
print array
print 'min:', np.min(array)    # 최소값
print 'mean:', np.mean(array)    # 평균
print 'median:', np.median(array)    # 중앙값
print 'max:', np.max(array)    # 최대값
print 'std:', np.std(array)    # 표준편차
print 'argmin:', np.argmin(array)    # 최소값 index 반환
print 'argmax:', np.argmax(array)    # 최대값 index 반환
print 'sum:', np.sum(array)    # 합계
print 'sqrt:', np.sqrt(array)    # 제곱근

#bit-wise XOR
a = 10
print 10 ^ 2
print 17 ^ 8

"""
Explanation: .reshape(x, y): x, y배열로 재배열
End of explanation
"""


