공부 기록
Numpy(0721_day 1) 본문
Numpy 성능 비교¶
In [1]:
import numpy as np
In [3]:
my_list = list(range(1000000))
- 매직 명령어 확인하기¶
In [4]:
%magic
- %time: 명령어가 실행되는데 걸리는 시간 반환¶
- %time 뒤에 for문을 추가하면 해당 횟수만큼 반복 후 평균 시간 반환해준다.¶
In [9]:
%time for _ in range(10): my_list2 = [x * 2 for x in my_list]
Wall time: 1.3 s
In [10]:
my_arr = np.arange(1000000)
In [11]:
type(my_arr) # ndarray: n-dimensional array, n차원 배열
Out[11]:
numpy.ndarray
- numpy는 브로드캐스팅이 가능(아래처럼 상수값을 곱해주면 크기가 자동으로 브로드캐스팅되서 연산이 된다.)¶
In [13]:
%time for _ in range(10): my_arr * 2
Wall time: 32 ms
1. Numpy ndarray(다차원 배열 객체)¶
- np.random.randn(행, 열) : 표준 정규분포를 따르는 랜덤값 생성¶
In [14]:
data = np.random.randn(2, 3)
data
Out[14]:
array([[ 3.48157103, 0.77581371, -0.23955768], [-0.5012058 , -0.34951226, 0.77484553]])
In [15]:
type(data)
Out[15]:
numpy.ndarray
In [16]:
data.shape
Out[16]:
(2, 3)
In [17]:
data * 10
Out[17]:
array([[34.81571027, 7.75813706, -2.39557681], [-5.01205799, -3.4951226 , 7.74845534]])
In [18]:
data + data
Out[18]:
array([[ 6.96314205, 1.55162741, -0.47911536], [-1.0024116 , -0.69902452, 1.54969107]])
- data.dtype: data의 내부 값 타입이 무엇인지 알려줌¶
In [19]:
data.dtype
Out[19]:
dtype('float64')
1.1 ndarray 생성하기¶
In [22]:
data1 = [6, 7.5, 8, 0, 1]
arr1 = np.array(data1)
arr1
Out[22]:
array([6. , 7.5, 8. , 0. , 1. ])
In [23]:
type(arr1)
Out[23]:
numpy.ndarray
In [24]:
data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
arr2 = np.array(data2)
arr2
Out[24]:
array([[1, 2, 3, 4], [5, 6, 7, 8]])
- 원소가 5개인 1차원 배열 객체¶
In [26]:
arr1.shape
Out[26]:
(5,)
In [28]:
arr1.ndim
Out[28]:
1
In [30]:
arr1.dtype
Out[30]:
dtype('float64')
- 원소가 8개인 2차원 배열 객체, 2x4행렬¶
In [27]:
arr2.shape
Out[27]:
(2, 4)
In [29]:
arr2.ndim
Out[29]:
2
In [31]:
arr2.dtype
Out[31]:
dtype('int32')
- np.zeros(개수 or (행, 열)): 0으로 초기화된 배열 생성¶
In [32]:
np.zeros(10)
Out[32]:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
In [35]:
np.zeros((3, 6))
Out[35]:
array([[0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0.]])
- np.ones(개수 or (행, 열)): 1로 초기화된 배열 생성¶
In [33]:
np.ones(10)
Out[33]:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
In [36]:
np.ones((3, 6))
Out[36]:
array([[1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.]])
- np.empty((shape)): shape만큼 가비지값 들어간 배열 생성¶
In [38]:
np.empty((2, 3, 4)) # 3차원
Out[38]:
array([[[6.23042070e-307, 4.67296746e-307, 1.69121096e-306, 7.56598449e-307], [1.78019082e-306, 1.33511018e-306, 1.33511969e-306, 6.23037996e-307], [6.23053954e-307, 9.34609790e-307, 8.45593934e-307, 9.34600963e-307]], [[1.60220528e-306, 1.78021119e-306, 1.37962117e-306, 1.78020169e-306], [1.37961641e-306, 1.86919649e-306, 1.42417221e-306, 1.60219306e-306], [6.89811941e-307, 6.23059386e-307, 9.34609111e-307, 2.56765117e-312]]])
In [39]:
np.arange(15)
Out[39]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
1.2 ndarray의 dtype¶
In [41]:
arr1 = np.array([1, 2, 3], dtype=np.float64)
arr1
Out[41]:
array([1., 2., 3.])
In [44]:
arr1.dtype
Out[44]:
dtype('float64')
In [45]:
arr2 = np.array([1, 2, 3], dtype=np.int32)
arr2
Out[45]:
array([1, 2, 3])
In [46]:
arr2.dtype
Out[46]:
dtype('int32')
In [47]:
arr = np.array([1, 2, 3, 4, 5])
arr.dtype
Out[47]:
dtype('int32')
- arr.astype(데이터타입): arr를 지정한 데이터 타입으로 바꿔줌¶
In [49]:
float_arr = arr.astype(np.float64)
float_arr.dtype
Out[49]:
dtype('float64')
In [50]:
arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
arr
Out[50]:
array([ 3.7, -1.2, -2.6, 0.5, 12.9, 10.1])
In [51]:
arr.dtype
Out[51]:
dtype('float64')
- float타입을 int타입으로 변환하면 데이터 손실이 일어남¶
In [52]:
arr.astype(np.int32)
Out[52]:
array([ 3, -1, -2, 0, 12, 10])
In [53]:
numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
numeric_strings.astype(float)
Out[53]:
array([ 1.25, -9.6 , 42. ])
In [54]:
numeric_strings.astype(float).dtype
Out[54]:
dtype('float64')
- 현재객체.astype(다른객체.dtype): 현재 객체의 데이터타입을 다른 객체의 데이터타입으로 바꿀 때¶
In [55]:
int_array = np.arange(10)
calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)
int_array.astype(calibers.dtype)
Out[55]:
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [60]:
# 둘은 같은 방법
empty_uint32_1 = np.empty(8, dtype='u4')
empty_uint32_2 = np.empty(8, dtype=np.uint32)
print(empty_uint32_1)
print(empty_uint32_2)
[ 0 1 0 0 880 0 768 192] [ 1 1 0 0 880 0 16777984 604]
1.3 Numpy 배열의 산술연산¶
In [61]:
arr = np.array([[1., 2., 3.], [4., 5., 6.]])
arr
Out[61]:
array([[1., 2., 3.], [4., 5., 6.]])
- 여기서 *는 행렬의 곱셈이 아니라 같은 위치 값 곱하는 연산¶
In [62]:
arr * arr
Out[62]:
array([[ 1., 4., 9.], [16., 25., 36.]])
In [63]:
arr - arr
Out[63]:
array([[0., 0., 0.], [0., 0., 0.]])
In [64]:
1/arr
Out[64]:
array([[1. , 0.5 , 0.33333333], [0.25 , 0.2 , 0.16666667]])
In [65]:
arr ** 2
Out[65]:
array([[ 1., 4., 9.], [16., 25., 36.]])
In [66]:
arr ** 0.5
Out[66]:
array([[1. , 1.41421356, 1.73205081], [2. , 2.23606798, 2.44948974]])
In [67]:
arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
arr2
Out[67]:
array([[ 0., 4., 1.], [ 7., 2., 12.]])
- 두 ndarray의 비교는 각 자리의 원소를 비교해 True, False로 결과를 반환¶
In [68]:
arr2 > arr
Out[68]:
array([[False, True, False], [ True, False, True]])
1.4 색인과 슬라이싱 기초¶
In [71]:
arr = np.arange(10)
arr
Out[71]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [73]:
arr[5]
Out[73]:
5
In [74]:
arr[5:8]
Out[74]:
array([5, 6, 7])
- 배열을 슬라이싱 후 값을 넣으면 해당 위치의 값이 모두 바뀜(넘파이에서는 슬라이싱한 개수와 넣어줄 개수 같지 않아도 가능)¶
In [76]:
arr[5:8] = 12
arr
Out[76]:
array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
In [78]:
arr = np.arange(10)
arr
Out[78]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
- brr = arr[5:8]을 할 때 copy한 거라고 생각할 수 있는데 실제로는 주소를 공유함, 따라서 arr[5:8]값을 바꾸고 brr을 다시 출력하면 값이 바껴있음¶
In [79]:
brr = arr[5:8]
brr
Out[79]:
array([5, 6, 7])
In [80]:
arr[5:8] = 12
arr
Out[80]:
array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
In [81]:
brr
Out[81]:
array([12, 12, 12])
- 파이썬과 비교¶
1) 파이썬은 슬라이싱한 개수와 넣어줄 값의 개수를 맞춰야함¶
In [83]:
a = [1, 2, 3, 4, 5, 6, 7]
a[3:5] = [12, 12] # 파이썬의 개수 맞춰줘야함
a
Out[83]:
[1, 2, 3, 12, 12, 6, 7]
2) 슬라이싱한 부분을 변수에 넣고 a자체를 바꿔도 변수가 갖고있는 값은 바뀌지 않음¶
In [84]:
a = list(range(10))
a
Out[84]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [85]:
b = a[5:8]
b
Out[85]:
[5, 6, 7]
In [86]:
a[5:8] = [12, 12 ,12]
a
Out[86]:
[0, 1, 2, 3, 4, 12, 12, 12, 8, 9]
In [87]:
b
Out[87]:
[5, 6, 7]
- ndarray에서는 원본 데이터를 바꾸면 슬라이싱을 저장한 부분도 바뀌고, 반대로의 경우에도 바뀜¶
In [88]:
arr
Out[88]:
array([ 0, 1, 2, 3, 4, 12, 12, 12, 8, 9])
In [89]:
arr_slice = arr[5:8]
arr_slice
Out[89]:
array([12, 12, 12])
In [90]:
arr_slice[1] = 12345
arr_slice
Out[90]:
array([ 12, 12345, 12])
In [91]:
arr
Out[91]:
array([ 0, 1, 2, 3, 4, 12, 12345, 12, 8, 9])
In [92]:
arr_slice[:] = 64
arr_slice
Out[92]:
array([64, 64, 64])
In [93]:
arr
Out[93]:
array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9])
In [156]:
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d
Out[156]:
array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
In [95]:
arr2d.shape
Out[95]:
(3, 3)
In [96]:
arr2d.ndim
Out[96]:
2
- ndarray의 인덱싱, ([0][0]은 [0, 0]과 같음)¶
In [97]:
arr2d[2]
Out[97]:
array([7, 8, 9])
In [98]:
arr2d[0][2]
Out[98]:
3
In [99]:
arr2d[0, 2]
Out[99]:
3
In [103]:
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d
Out[103]:
array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]])
In [104]:
arr3d.shape
Out[104]:
(2, 2, 3)
- 3차원 ndarray를 한번 색인하면 --> 2차원 ndarray 반환¶
In [109]:
arr3d[0]
Out[109]:
array([[1, 2, 3], [4, 5, 6]])
In [115]:
arr3d[0].ndim
Out[115]:
2
- 3차원 ndarray를 두번 색인하면 --> 1차원 ndarray 반환¶
In [106]:
arr3d[0][1]
Out[106]:
array([4, 5, 6])
In [114]:
arr3d[0][1].ndim
Out[114]:
1
- 3차원 ndarray를 세번 색인하면 --> 하나의 값 반환¶
In [111]:
arr3d[0][1][2]
Out[111]:
6
In [118]:
arr3d[0, 1, 2]
Out[118]:
6
In [116]:
arr3d[0][1][2].ndim
Out[116]:
0
In [117]:
type(arr3d[0][1][2])
Out[117]:
numpy.int32
In [119]:
arr3d
Out[119]:
array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]])
In [120]:
arr3d[0]
Out[120]:
array([[1, 2, 3], [4, 5, 6]])
- .copy() 쓰면 주소 공유 아니라 값 자체를 복사¶
In [121]:
old_values = arr3d[0].copy()
- arr3d[0] = 42하면 자동으로 브로드캐스팅되서 모든 값에 42가 들어감¶
In [122]:
arr3d[0] = 42
In [123]:
arr3d
Out[123]:
array([[[42, 42, 42], [42, 42, 42]], [[ 7, 8, 9], [10, 11, 12]]])
In [126]:
old_values
Out[126]:
array([[1, 2, 3], [4, 5, 6]])
In [128]:
arr3d[0] = old_values
arr3d
Out[128]:
array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]]])
In [129]:
arr3d[1, 0]
Out[129]:
array([7, 8, 9])
In [130]:
x = arr3d[1]
x
Out[130]:
array([[ 7, 8, 9], [10, 11, 12]])
In [131]:
x[0]
Out[131]:
array([7, 8, 9])
- 슬라이스 선택하기, arr[행, 열]¶
In [132]:
arr
Out[132]:
array([ 0, 1, 2, 3, 4, 64, 64, 64, 8, 9])
In [133]:
arr[1:6]
Out[133]:
array([ 1, 2, 3, 4, 64])
In [134]:
arr2d
Out[134]:
array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
- arr2d[:] : arr2d[0]과 arr2d[1]을 가져와라¶
In [135]:
arr2d[:2]
Out[135]:
array([[1, 2, 3], [4, 5, 6]])
In [138]:
arr2d[:2, 1:]
Out[138]:
array([[2, 3], [5, 6]])
In [148]:
arr2d[:2, 1:].ndim
Out[148]:
2
* 여기서는 일단 arr2d[:2]를 하고 난 후에 거기서 [1:]까지 출력한 것이므로 다음과 같이 나옴 ======================================¶
* 정수를 색인할 때는 [][]와 [ , ]를 같이 사용할 수 있지만 numpy에서 슬라이싱은 [:, :]과 같이 콤마로 연결해주기!¶
In [145]:
arr2d[:2][1:]
Out[145]:
array([[4, 5, 6]])
In [149]:
tmp = arr2d[:2]
tmp
Out[149]:
array([[1, 2, 3], [4, 5, 6]])
In [150]:
tmp[1:]
Out[150]:
array([[4, 5, 6]])
In [142]:
arr2d[1][:2]
Out[142]:
array([4, 5])
* 슬라이싱 시 하나를 정수로 지정하면 차원이 줄어든다.¶
In [151]:
arr2d[1][:2].ndim
Out[151]:
1
In [143]:
arr2d[1, :2]
Out[143]:
array([4, 5])
In [152]:
arr2d[1, :2].ndim
Out[152]:
1
In [146]:
arr2d[:2, 2]
Out[146]:
array([3, 6])
In [147]:
arr2d[:2, 2].ndim
Out[147]:
1
================================================================================================================
In [157]:
arr2d[:2, 1:] = 0
arr2d
Out[157]:
array([[1, 0, 0], [4, 0, 0], [7, 8, 9]])
png 이미지를 사용해서 슬라이싱 연습¶
- 현재 디렉토리에 png파일 있는지 확인¶
In [1]:
!dir psj.png
C 드라이브의 볼륨에는 이름이 없습니다. 볼륨 일련 번호: B4D9-1690 C:\Users\Playdata\Documents\Numpy 디렉터리 2021-07-21 오후 05:31 182,704 psj.png 1개 파일 182,704 바이트 0개 디렉터리 182,365,065,216 바이트 남음
In [2]:
import matplotlib.pyplot as plt
- 해당 png파일 읽어서 변수에 저장¶
In [3]:
img = plt.imread('psj.png')
In [163]:
img.shape
Out[163]:
(333, 365, 4)
In [164]:
type(img)
Out[164]:
numpy.ndarray
In [165]:
img.dtype
Out[165]:
dtype('float32')
- img[0][0][0] 값이 0~1 사이의 값인 이유는 255로 나눴기 때문¶
In [4]:
img[0][0][0]
Out[4]:
0.83137256
- plt.imshow(ndarray값): 이미지 보기¶
In [5]:
plt.imshow(img)
Out[5]:
<matplotlib.image.AxesImage at 0x2335243c430>
- 흑백은 0~255, 0: 검은색, 255: 흰색으로 표현 가능¶
- 컬러는 한 픽셀을 표현하기 위해 4장의 채널이 필요함, 1~3은 R, G, B채널이고 4번째 채널은 알파채널(투명도)¶
- 현재 사진이 컬러라서 img.shape 했을 때 마지막 값이 4임¶
In [168]:
img.shape
Out[168]:
(333, 365, 4)
- img[0][0]: 여기서 나온 4가지 값은 처음부터 R, G, B, alpha값 이다.¶
In [170]:
img[0][0]
Out[170]:
array([0.83137256, 0.8509804 , 0.8666667 , 1. ], dtype=float32)
- 좌측 상단의 R채널 픽셀값(광도)¶
In [171]:
img[0][0][0]
Out[171]:
0.83137256
- 좌측 상단의 G채널 픽셀값(광도)¶
In [173]:
img[0][0][1]
Out[173]:
0.8509804
- 좌측 상단의 B채널 픽셀값(광도)¶
In [174]:
img[0][0][2]
Out[174]:
0.8666667
- 아래와 같이 실행하면 좌측 상단의 픽셀 하나가 빨간색으로 바뀜(그림 작아서 안보이지만)¶
In [175]:
img[0][0][0] = 1
img[0][0][1] = 0
img[0][0][2] = 0
In [176]:
plt.imshow(img)
Out[176]:
<matplotlib.image.AxesImage at 0x25c3b41d970>
In [177]:
img[0:10, 0:10, 0] = 1
img[0:10, 0:10, 1] = 0
img[0:10, 0:10, 2] = 0
plt.imshow(img)
Out[177]:
<matplotlib.image.AxesImage at 0x25c3b662a90>
- 액자 만들기¶
In [13]:
R, G, B = 0.5, 0.1, 0.8
# 위쪽
img[0:10, :, 0] = R
img[0:10, :, 1] = G
img[0:10, :, 2] = B
# 왼쪽
img[:, 0:10, 0] = R
img[:, 0:10, 1] = G
img[:, 0:10, 2] = B
# 오른쪽
img[:, -10:, 0] = R
img[:, -10:, 1] = G
img[:, -10:, 2] = B
#아래쪽
img[-10:, :, 0] = R
img[-10:, :, 1] = G
img[-10:, :, 2] = B
plt.imshow(img)
Out[13]:
<matplotlib.image.AxesImage at 0x23353714340>
In [15]:
img = plt.imread('psj.png')
- 색상 반전¶
In [17]:
img[:, :, :3] = 1-img[:, :, :3]
plt.imshow(img)
Out[17]:
<matplotlib.image.AxesImage at 0x23351bc3310>
'playdata' 카테고리의 다른 글
Pandas(0727_day3) (0) | 2021.07.27 |
---|---|
Pandas(0726_day2) - 실습_자동차 연비 분석 (탐색 및 통계 요약) (0) | 2021.07.26 |
Pandas(0726_day2) (0) | 2021.07.26 |
Pandas(0723_day1) (0) | 2021.07.23 |
Numpy(0722_day2) (0) | 2021.07.22 |
Comments