import random
import numpy as np
import matplotlib.pyplot as plt
my_arr = np.arange(1000000) ## range()와 거의 동일. aragne()는 실수도 가능
my_list = list(range(1000000))
%time for _ in range(10): my_arr2 = my_arr * 2 # ndarray 연산 시간 측정 ##numpy가 훨씬 빠름
%time for _ in range(10): my_list2 = [x * 2 for x in my_list] # list 연산 시간 측정
#결과:
CPU times: user 15 ms, sys: 11.8 ms, total: 26.9 ms
Wall time: 73.8 ms
CPU times: user 1.14 s, sys: 222 ms, total: 1.36 s
Wall time: 2.48 s
"""
표준 정규 분포(평균 0, 표준편차 1)에서 난수 ndarray 생성하기
ndarray 이름: data
ndarray 크기: (2, 3)
"""
mu, sigma = 0.0, 1.0 ## 각각 평균값, 표준편차
size = (2, 3)
data = np.random.normal(mu, sigma, size)
print(data)
print(type(data))
#결과:
[[ 0.69306021 0.95109389 0.70530025][ 0.41356579 -0.69474558 -0.77715936]]
<class 'numpy.ndarray'>
"""
[문제 2] 0부터 1사이의 균일 분포에서 난수 ndarray 생성하기
ndarray 이름: data2
ndarray 크기: (2, 3)
"""
low = 0
high = 1
size = (2, 3)
data2 = np.random.uniform(low, high, size)
print(data)
print(type(data))
#결과:
[[-0.85082725 0.58764742 1.29330679][-0.66819439 -0.96406366 -0.44472203]]
<class 'numpy.ndarray'>
"""
균일 분포에서 정수 난수 1개 생성하기
난수 객체 이름: data3
난수 범위: (1, 20)
"""
low = 1
high = 20
data3 = np.random.randint(low, high, 1)
print(data3)
#결과:
[12]
"""
data 배열에 10 곱하기
"""
data_mul = data * 10.0
print(data_mul)
#결과:
[[-8.50827252 5.87647418 12.93306788][-6.68194392 -9.6406366 -4.44722032]]
"""
data 배열에 data 배열 더하기
"""
data_sum = data + data
print(data_sum)
#결과:
[[-1.7016545 1.17529484 2.58661358][-1.33638878 -1.92812732 -0.88944406]]
"""
data 배열 크기 출력하기
"""
print(data.shape)
#결과:
(2, 3)
"""
data 데이터타입 출력하기
"""
print(data.dtype)
#결과:
float64
"""
아래 리스트를 이용하여 NumPy ndarray 생성하기
ndarray 이름: arr1
"""
data1 = [6, 7.5, 8, 0, 1]
print(type(data1))
arr1 = np.array(data1) ## 파이썬 리스트(list)나 튜플(tuple)과 같은 반복 가능한(iterable) 객체를 입력으로 받아서 NumPy 배열(ndarray)로 변환해주는 함수
print(type(arr1))
#결과:
<class 'list'>
<class 'numpy.ndarray'>
"""
아래 리스트를 이용하여 ndarray 생성하기
ndarray 이름: arr2
"""
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]] ##2차원
arr2 = np.array(data2)
print(arr2.shape) ##shape은 numpy의 라이브러리 함수
#결과:
(2, 4)
"""
크기 10이고 0으로 초기화한 ndarray 생성하기
ndarray 이름: data_zero
"""
data_zero = np.zeros(10)
print(data_zero)
#결과:
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
"""
크기 (3, 6)이고 0으로 초기화한 ndarray 생성하기
ndarray 이름: data_zero1
"""
size = (3,6)
data_zero1 = np.zeros(size)
print(data_zero1)
#결과:
[[0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0.]]
"""
크기 (2, 3, 2)이고 초기화하지 않은 ndarray 생성하기
ndarray 이름: data_empty
"""
size = (2,3,2)
data_empty = np.empty(size) ## empty()는 NumPy 라이브러리에서 제공하는 함수 중 하나로, 지정된 크기의 비어있는(empty) 배열을 생성하는 함수
print(data_empty) ## NumPy 배열을 출력할 때, 기본적으로 배열의 내용을 보여주는 것 외에도 해당 배열 객체의 정보를 요약해서 보여줍니다. 따라서 print(data_empty)를 호출하면 두 개의 출력 결과가 나타납니다.
data_empty = np.empty(size, dtype = np.int8)
print(data_empty)
#결과:
[[[4.78419221e-310 0.00000000e+000][0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000]]
[[0.00000000e+000 0.00000000e+000][0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000]]]
[[[1 0][0 0]
[0 0]]
[[0 0][0 0]
[0 0]]]
"""
0 부터 15 전까지 시퀀스 배열 생성하기
"""
data_sequence = np.arange(0, 15)
print(data_sequence)
#결과:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
"""
0 부터 2 전까지 스텝크기 0.3 인 시퀀스 배열 생성하기
"""
data_sequence2 = np.arange(0, 2, 0.3)
print(data_sequence2)
#결과:
[0. 0.3 0.6 0.9 1.2 1.5 1.8]
"""
아래의 리스트를 이용하여 데이터타입이 np.float64인 ndarray 생성하기
ndarray 이름: arr1
"""
data_list = [1, 2, 3]
arr1 = np.asarray(data_list, dtype = np.float64) ##리스트를 ndarray로 변환
print(arr1)
print(arr1.dtype)
print(type(arr1))
#결과:
[1. 2. 3.]
float64
<class 'numpy.ndarray'>
asarray()와 array()는 모두 NumPy 라이브러리에서 제공하는 함수로, 파이썬 리스트(list)나 튜플(tuple)과 같은 반복 가능한(iterable) 객체를 NumPy 배열(ndarray)로 변환하는 역할을 합니다. 그러나 두 함수에는 몇 가지 차이점이 있습니다.
복사 여부:
asarray() : 입력된 객체가 이미 NumPy 배열인 경우에는 새로운 복사본을 생성하지 않고 그대로 반환합니다. 따라서 메모리를 절약할 수 있습니다.
array() : 입력된 객체가 이미 NumPy 배열인 경우에도 항상 새로운 복사본을 생성하여 반환합니다.
dtype 지정:
asarray() : 기본적으로 입력된 객체의 데이터 타입(dtype)을 따릅니다.
array() : 기본적으로 float 타입으로 설정됩니다. 하지만 dtype 인자를 사용하여 원하는 데이터 타입으로 명시적으로 지정할 수 있습니다.
소스 코드에서의 사용 방법:
asarray()는 주로 이미 다른 형태의 배열이나 리스트 등의 데이터 구조가 있는 경우, 해당 구조를 유지하면서 NumPy 배열로 변환할 때 사용됩니다.
array()는 주어진 데이터 구조와 상관없이 항상 새로운 NumPy 배열을 생성하고 싶은 경우에 사용됩니다.
"""
아래 2개의 ndarray 간의 element-wise 곱하기
"""
arr1 = np.array([[1., 2., 3.], [4., 5., 6.]])
arr2 = np.array([[4., 5., 6.], [1., 2., 3.]])
arr3 = np.multiply(arr1, arr2)
print(arr3)
#결과:
[[ 4. 10. 18.][ 4. 10. 18.]]
"""
아래 ndarray에 element-wise 0.5 거듭제곱하기
"""
arr1 = np.array([[1., 2., 3.], [4., 5., 6.]])
arr3 = np.power(arr1, 0.5)
print(arr3)
#결과:
[[1. 1.41421356 1.73205081][2. 2.23606798 2.44948974]]
"""
arr1이 3.5보다 큰 배열 인덱스 출력하기
"""
arr1 = np.array([1., 2., 3., 4., 5., 6.])
print(np.where(arr1 > 3.5, True, False))
print(np.where(arr1 > 3.5)) ##조건에 부합하는 인덱스 출력
print(arr1 > 3.5)
#결과:
[False False False True True True]
(array([3, 4, 5]),)
[False False False True True True]
where()는 지정된 조건에 따라 요소별로 값을 선택하는 역할을 합니다. where() 함수를 사용하면 배열의 각 요소에 대해 조건을 검사하고, 조건을 만족하는 경우에는 해당 요소의 값을 선택하여 새로운 배열을 생성할 수 있습니다.
where() 함수의 기본 형식은 다음과 같습니다:
"""
arr2중에서 가장 큰 값 인덱스 출력하기
"""
arr2 = np.array([4., 5., 6., 1., 2., 3.])
print(np.where(arr2 == np.max(arr2))) ##조건에 부합하는 인덱스 출력
print(np.argmax(arr2)) ##주로 많이 사용 ## 주어진 배열에서 최댓값의 인덱스를 반환하는 역할을 한다
#결과:
(array([2]),)
2
"""
arr2 오름차순으로 정렬 후 인덱스 출력
""'
arr2 = np.array([4., 5., 6., 1., 2., 3.])
print(np.sort(arr2))
print(np.argsort(arr2)) ##인덱스 출력 ## 주어진 배열을 정렬한 후에 해당 요소의 인덱스를 반환하는 역할을 한다
#결과:
[1. 2. 3. 4. 5. 6.][3 4 5 0 1 2]
"""
아래 arr 배열 인덱스 5부터 8전까지의 값을 12로 변경하기
"""
arr = np.arange(10)
print(arr)
for i in np.argsort(arr):
if i in range(5, 8):
arr[i] = 12
else:
pass
print(arr)
arr = np.arange(10)
arr = np.array([12 if idx >= 5 and idx < 8 else arr[idx] for idx,_ in enumerate(arr)])
print(arr)
#결과:
[0 1 2 3 4 5 6 7 8 9][ 0 1 2 3 4 12 12 12 8 9]
[ 0 1 2 3 4 12 12 12 8 9]
"""
문제 31의 arr_slice 배열의 모든 값을 64로 변경하고 arr 배열 출력하기
"""
arr_slice = np.zeros(10)
print(arr_slice)
arr_slice[:] = 64
print(arr_slice)
#결과:
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.][64. 64. 64. 64. 64. 64. 64. 64. 64. 64.]
"""
문제 22의 arr_slice 배열의 복사본을 생성하고 모든 값을 9999로 변경하고 arr 배열 출력하기
"""
arr_slice_copy = arr_slice.copy()
arr_slice_copy[:] = 9999
print(arr_slice)
print(arr_slice_copy)
#결과:
[64. 64. 64. 64. 64. 64. 64. 64. 64. 64.][9999. 9999. 9999. 9999. 9999. 9999. 9999. 9999. 9999. 9999.]
copy()는 NumPy 배열 객체의 메소드로, 배열의 깊은 복사(deep copy)를 생성하는 역할을 합니다. copy() 메소드를 사용하면 기존 배열과 동일한 요소를 가진 새로운 배열을 생성할 수 있습니다.
깊은 복사(deep copy)인 copy() 메소드는 원본 데이터와 완전히 분리된 새로운 데이터 객체를 만들기 때문에,
원본 데이터와 복사본 간에 어떠한 변경도 서로에게 영향을 주지 않습니다.
따라서 원본 데이터가 변경되더라도 복사본 데이터는 변하지 않습니다.
"""
np.arange(10)을 선언하고 역순으로 정렬하기
"""
arange = np.arange(10)
print(arange)
reverse_arange = np.flip(arange) ## NumPy 배열을 복사(copy)하여 요소들을 역순으로 재배열한 새로운 배열을 생성
print(reverse_arange)
#결과:
[0 1 2 3 4 5 6 7 8 9][9 8 7 6 5 4 3 2 1 0]