day 7 파이썬 배열(array)과 표(table)
파이썬 배열(array)과 표(table)
배열
평균 계산하기
total = 0
count = 0
numbers = input("Enter a number : (<Enter Key> to quit)")
while numbers != "":
try:
x = float(numbers)
count += 1
total = total + x
except ValueError:
print('NOT a number! Ignored..')
numbers = input("Enter a number : (<Enter Key> to quit)")
avg = total / count
print("\n average is", avg)
..
..
Enter a number : (<Enter Key> to quit) 1
Enter a number : (<Enter Key> to quit) 1
Enter a number : (<Enter Key> to quit) 3
Enter a number : (<Enter Key> to quit) 4
Enter a number : (<Enter Key> to quit)
average is 2.25
평균, 표준편차, 중앙값 계산
# 2개 이상의 숫자를 입력받아 리스트에 저장하는 함수
def numbers():
X=[] # X에 빈 리스트를 할당합니다.
while True:
number = input("Enter a number (<Enter key> to quit)")
while number !="":
try:
x = float(number)
X.append(x) # float형으로 변환한 숫자 입력을 리스트에 추가합니다.
except ValueError:
print('>>> NOT a number! Ignored..')
number = input("Enter a number (<Enter key> to quit)")
if len(X) > 1: # 저장된 숫자가 2개 이상일 때만 리턴합니다.
return X
X=numbers()
print('X :', X)
..
..
Enter a number (<Enter key> to quit) 1
Enter a number (<Enter key> to quit) 2
Enter a number (<Enter key> to quit) 3
Enter a number (<Enter key> to quit)
X : [1.0, 2.0, 3.0]
다른 언어에서는 배열은 크기를 정해 놓아야 하는 경우가 많습니다. 대표적으로 C언어가 그러하지요. 그러니깐, 배열 변수를 만들 때 처음에 원소가 몇 개 들어갈 수 있다고 정해놓아야 합니다. 그러나 파이썬의 리스트는 그렇지 않습니다. 파이썬의 리스트는 임의의 데이터 타입을 담을 수 있는 가변적 연속열(Sequence)형입니다. 즉, 파이썬 리스트는 동적 배열(Dynamic Array) 입니다.
import array as arr
mylist = [1, 2, 3] # 이것은 파이썬 built-in list입니다.
print(type(mylist))
mylist.append('4') # mylist의 끝에 character '4'를 추가합니다.
print(mylist)
mylist.insert(1, 5) # mylist의 두번째 자리에 5를 끼워넣습니다.
print(mylist)
myarray = arr.array('i', [1, 2, 3]) # 이것은 array입니다. import array를 해야 쓸 수 있습니다.
print(type(myarray))
# 아래 라인의 주석을 풀고 실행하면 에러가 납니다.
#myarray.append('4') # myarray의 끝에 character '4'를 추가합니다.
print(myarray)
myarray.insert(1, 5) # myarray의 두번째 자리에 5를 끼워넣습니다.
print(myarray)
-
list는 별도의 import가 필요없지만 array를 사용하기 위해서는 import를 해주어야 합니다. 파이썬에서 array는 built-in이 아닙니다.
-
list 안의 element 사이에 다른 타입의 자료형이 허용됩니다. 숫자로만 이루어진 list에 문자열 element를 추가할 수 있습니다. 그러나 array는 처음부터 element의 유형을 지정해서 생성하며, 지정되지 않은 다른 타입의 element 추가가 허용되지 않습니다. 이러한 array의 특성은 다음에 나오는 NumPy에도 동일하게 적용됩니다.
리스트를 활용한 시그마의 표현
total = 0.0
for i in range(len(X)):
total = total + X[i]
mean = total / len(X)
print('sum of X: ', total)
..
..
sum of X: 6.0
중앙값
def median(nums): # nums : 리스트를 지정하는 매개변수
nums.sort() # sort()로 리스트를 순서대로 정렬
size = len(nums)
p = size // 2
if size % 2 == 0: # 리스트의 개수가 짝수일때
pr = p # 4번째 값
pl = p-1 # 3번째 값
mid= float((nums[pl]+nums[pr])/2)
else: # 리스트의 개수가 홀수일때
mid = nums[p]
return mid
print('X :', X)
median(X) # 매개변수의 값으로 X를 사용함
..
..
X : [1.0, 2.0, 3.0]
2.0
표준편차와 평균
def means(nums):
total = 0.0
for i in range(len(nums)):
total = total + nums[i]
return total / len(nums)
means(X)
..
..
2.0
avg = means(X)
def std_dev(nums, avg):
texp = 0.0
for i in range(len(nums)):
texp = texp + (nums[i] - avg)**2 # 각 숫자와 평균값의 차이의 제곱을 계속 더한 후
return (texp/(len(nums)-1)) ** 0.5 # 그 총합을 숫자개수-1로 나눈 값의 제곱근을 리턴합니다.
std_dev(X,avg)
..
..
1.0
전체 코드 : main()함수
def numbers():
X=[]
while True:
number = input("Enter a number (<Enter key> to quit)")
while number !="":
try:
x = float(number)
X.append(x)
except ValueError:
print('>>> NOT a number! Ignored..')
number = input("Enter a number (<Enter key> to quit)")
if len(X) > 1:
return X
def median(nums):
nums.sort()
size = len(nums)
p = size // 2
if size % 2 == 0:
pr = p
pl = p+1
mid = float((nums[pl]+nums[pr])/2)
else:
mid = nums[p]
return mid
def means(nums):
total = 0.0
for i in range(len(nums)):
total = total + nums[i]
return total / len(nums)
def std_dev(nums, avg):
texp = 0.0
for i in range(len(nums)):
texp = texp + (nums[i] - avg) ** 2
return (texp/(len(nums)-1)) ** 0.5
def main():
X = numbers()
med = median(X)
avg = means(X)
std = std_dev(X, avg)
print("당신이 입력한 숫자{}의 ".format(X))
print("중앙값은{}, 평균은{}, 표준편차는{}입니다.".format(med, avg, std))
if __name__ == '__main__':
main()
med = median(X)
avg = means(X)
std = std_dev(X, avg)
print("당신이 입력한 숫자{}의 ".format(X))
print("중앙값은{}, 평균은{}, 표준편차는{}입니다.".format(med, avg, std))
..
..
당신이 입력한 숫자[1.0, 2.0, 3.0]의
중앙값은2.0, 평균은2.0, 표준편차는1.0입니다.
numpy
우린 NumPy 이야기 해야죠? 여기는 NumPy 공식 사이트에요. 여기에 소개된 NumPy의 특징을 바탕으로 몇 가지 장점을 소개 드리면,
-
빠르고 메모리를 효율적으로 사용하여 벡터의 산술연산과 브로드캐스팅 연산을 지원하는 다차원 배열 ndarray 데이터 타입을 지원한다.
-
반복문을 작성할 필요 없이 전체 데이터 배열에 대해 빠른 연산을 제공하는 다양한 표준 수학 함수를 제공한다.
-
배열 데이터를 디스크에 쓰거나 읽을 수 있다. (즉, 파일로 저장한다는 뜻입니다)
-
선형대수, 난수발생기, 푸리에 변환 가능, C/C++ 포트란으로 쓰여진 코드를 통합한다.
import numpy as np
# 아래 A와 B는 결과적으로 같은 ndarray 객체를 생성합니다.
A = np.arange(5)
B = np.array([0,1,2,3,4]) # 파이썬 리스트를 numpy ndarray로 변환
# 하지만 C는 좀 다를 것입니다.
C = np.array([0,1,2,3,'4'])
# D도 A, B와 같은 결과를 내겠지만, B의 방법을 권합니다.
D = np.ndarray((5,), np.int64, np.array([0,1,2,3,4]))
print(A)
print(type(A))
print(B)
print(type(B))
print(C)
print(type(C))
print(D)
print(type(D))
..
..
[0 1 2 3 4]
<class 'numpy.ndarray'>
[0 1 2 3 4]
<class 'numpy.ndarray'>
['0' '1' '2' '3' '4']
<class 'numpy.ndarray'>
[0 1 2 3 4]
<class 'numpy.ndarray'>
크기 (size, shape, ndim)
size, shape, ndim는 각각 행렬 내 원소의 개수, 행렬의 모양, 행렬의 축(axis)의 개수를 의미합니다. reshape() 메소드는 행렬의 모양를 바꿔줍니다. 모양을 바꾸기 전후 행렬의 총 원소 개수(size)가 맞아야 해요.
A = np.arange(10)
print('A: ', A)
B = np.arange(10).reshape(2,5)
print('B: ', B)
C = np.arange(10).reshape(3,3) # 이 줄에서 에러가 날 것입니다.
print('C: ', C)
..
..
A: [0 1 2 3 4 5 6 7 8 9]
B: [[0 1 2 3 4]
[5 6 7 8 9]]
----> 5 C = np.arange(10).reshape(3,3) # 이 줄에서 에러가 날 것입니다.
6 print('C: ', C)
ValueError: cannot reshape array of size 10 into shape (3,3)
type
A= np.arange(6).reshape(2,3)
print(A)
print(A.dtype)
print(type(A))
B = np.array([0,1,2,3,4,5])
print(B)
print(B.dtype)
print(type(B))
C = np.array([0,1,2,3,'4',5])
print(C)
print(C.dtype)
print(type(C))
D = np.array([0,1,2,3,[4,5],6]) # 이런 ndarray도 만들어질까요?
print(D)
print(D.dtype)
print(type(D))
..
..
[[0 1 2]
[3 4 5]]
int64
<class 'numpy.ndarray'>
[0 1 2 3 4 5]
int64
<class 'numpy.ndarray'>
['0' '1' '2' '3' '4' '5']
<U21
<class 'numpy.ndarray'>
[0 1 2 3 list([4, 5]) 6]
object
<class 'numpy.ndarray'>
/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:16: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
app.launch_new_instance()
차이가 느껴지시나요? NumPy의 원소는 꼭 동일한 데이터 type이어야 합니다. NumPy의 메소드인 dtype은 NumPy ndarray의 “원소”의 데이터타입을 반환해요. 반면에 파이썬 내장함수인type(A)을 이용하면 행렬 A의 자료형이 반환됩니다.
여기서 재미있는 것은 D의 경우입니다. 이번에는 원소 하나를 list 객체로 바꿔 보았습니다. 위의 설명대로라면 NumPy의 원소는 꼭 동일한 데이터 type이어야 하므로 이번만큼은 에러가 날줄 알았는데, 떡하니 정상적으로 ndarray가 만들어집니다. 대신 D.dtype은 object를 리턴했습니다. 파이썬의 최상위 클래스는 바로 object입니다. 그러므로 Numpy는 dtype을 object로 지정해서라도 행렬 내 dtype을 일치시킬 수 있게 됩니다.
특수행렬
# 단위행렬
np.eye(3)
..
..
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
# 0 행렬
np.zeros([2,3])
..
..
array([[0., 0., 0.],
[0., 0., 0.]])
# 1행렬
np.ones([3,3])
..
..
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
브로드캐스트
A = np.arange(9).reshape(3,3)
A
..
..
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
# ndarray A에 2를 더했을 때,
2
A + 2
..
..
array([[ 2, 3, 4],
[ 5, 6, 7],
[ 8, 9, 10]])
# 3 X 3 행렬에 1 X 3 행렬을 더했을 때
A = np.arange(9).reshape(3,3)
B = np.array([1, 2, 3])
print(A)
print(B)
A+B
..
..
[[0 1 2]
[3 4 5]
[6 7 8]]
[1 2 3]
array([[ 1, 3, 5],
[ 4, 6, 8],
[ 7, 9, 11]])
# 3 X 3 행렬에 3 X 1 행렬을 더했을 때
A = np.arange(9).reshape(3,3)
C = np.array([[1], [2], [3]])
print(A)
print(C)
A+C
..
..
[[0 1 2]
[3 4 5]
[6 7 8]]
[[1]
[2]
[3]]
array([[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11]])
# 3 X 3 행렬에 1 X 2 행렬을 더하는 것은 허용되지 않습니다.
A = np.arange(9).reshape(3,3)
D = np.array([1, 2])
print(A)
print(D)
A+D
..
..
[[0 1 2]
[3 4 5]
[6 7 8]]
[1 2]
----> 6 A+D
ValueError: operands could not be broadcast together with shapes (3,3) (2,)
슬라이스와 인덱싱
# 0, 1을 인덱싱 하면 A의 첫번째 행에서 두번째 값을 참조합니다.
# 아래 두 결과는 정확히 같습니다.
print(A[0, 1])
print(B[1])
..
..
1
2
# 슬라이싱도 비슷합니다.
A[:-1]
array([[0, 1, 2],
[3, 4, 5]])
# 이 슬라이싱의 결과는
print(A[:,2:])
print(A[:,1:])
print(A[:,:])
# 이 슬라이싱의 결과와 동일합니다.
print(A[:,-1:])
print(A[:,-2:])
print(A[:,-3:])
..
..
# 위 그림과 비교해서 이해해 보세요.
[[2]
[5]
[8]]
[[1 2]
[4 5]
[7 8]]
[[0 1 2]
[3 4 5]
[6 7 8]]
[[2]
[5]
[8]]
[[1 2]
[4 5]
[7 8]]
[[0 1 2]
[3 4 5]
[6 7 8]]
A[:2, 1:]
..
..
array([[1, 2],
[4, 5]])
# 의사 난수를 생성하는 예제입니다. 여러번 실행해 보세요.
print(np.random.random()) # 0에서 1사이의 실수형 난수 하나를 생성합니다.
print(np.random.randint(0,10)) # 0~9 사이 1개 정수형 난수 하나를 생성합니다.
print(np.random.choice([0,1,2,3,4,5,6,7,8,9])) # 리스트에 주어진 값 중 하나를 랜덤하게 골라줍니다.
..
..
0.2062334447419517
6
8
random
# 의사 난수를 생성하는 예제입니다. 여러번 실행해 보세요.
print(np.random.random()) # 0에서 1사이의 실수형 난수 하나를 생성합니다.
print(np.random.randint(0,10)) # 0~9 사이 1개 정수형 난수 하나를 생성합니다.
print(np.random.choice([0,1,2,3,4,5,6,7,8,9])) # 리스트에 주어진 값 중 하나를 랜덤하게 골라줍니다.
..
..
0.3009068978646956
7
6
# 아래 2가지는 기능면에서 동일합니다. 원소의 순서를 임의로 뒤바꾸어 줍니다.
print(np.random.permutation(10))
print(np.random.permutation([0,1,2,3,4,5,6,7,8,9]))
..
..
[4 8 9 3 7 1 6 0 5 2]
[9 4 8 3 7 0 1 6 5 2]
# 아래 기능들은 어떤 분포를 따르는 변수를 임의로 표본추출해 줍니다.
# 이것은 정규분포를 따릅니다.
print(np.random.normal(loc=0, scale=1, size=5)) # 평균(loc), 표준편차(scale), 추출개수(size)를 조절해 보세요.
# 이것은 균등분포를 따릅니다.
print(np.random.uniform(low=-1, high=1, size=5)) # 최소(low), 최대(high), 추출개수(size)를 조절해 보세요.
..
..
[ 2.22796335 -2.04576583 0.10470438 0.77453122 -0.17394854]
[ 0.74907527 0.80715109 -0.16315793 0.6109862 -0.79868927]
A = np.arange(24).reshape(2,3,4)
print(A) # A는 (2,3,4)의 shape를 가진 행렬입니다.
print(A.T) # 이것은 A의 전치행렬입니다.
print(A.T.shape) # A의 전치행렬은 (4,3,2)의 shape를 가진 행렬입니다.
..
..
[[[ 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 12]
[ 4 16]
[ 8 20]]
[[ 1 13]
[ 5 17]
[ 9 21]]
[[ 2 14]
[ 6 18]
[10 22]]
[[ 3 15]
[ 7 19]
[11 23]]]
(4, 3, 2)
# np.transpose는 행렬의 축을 어떻게 변환해 줄지 임의로 지정해 줄 수 있는 일반적인 행렬 전치 함수입니다.
# np.transpose(A, (2,1,0)) 은 A.T와 정확히 같습니다.
B = np.transpose(A, (2,0,1))
print(A) # A는 (2,3,4)의 shape를 가진 행렬입니다.
print(B) # B는 A의 3, 1, 2번째 축을 자신의 1, 2, 3번째 축으로 가진 행렬입니다.
print(B.shape) # B는 (4,2,3)의 shape를 가진 행렬입니다.
..
..
[[[ 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 4 8]
[12 16 20]]
[[ 1 5 9]
[13 17 21]]
[[ 2 6 10]
[14 18 22]]
[[ 3 7 11]
[15 19 23]]]
(4, 2, 3)
기본 통계 데이터 계산 해보기
import numpy as np
# 6-3 스텝에서 사용하였던 함수입니다.
def numbers():
X = []
number = input("Enter a number (<Enter key> to quit)")
# 하지만 2개 이상의 숫자를 받아야 한다는 제약조건을 제외하였습니다.
while number != "":
try:
x = float(number)
X.append(x)
except ValueError:
print('>>> NOT a number! Ignored..')
number = input("Enter a number (<Enter key> to quit)")
return X
def main():
nums = numbers() # 이것은 파이썬 리스트입니다.
num = np.array(nums) # 리스트를 Numpy ndarray로 변환합니다.
print("합", num.sum())
print("평균값",num.mean())
print("표준편차",num.std())
print("중앙값",np.median(num)) # num.median() 이 아님에 유의해 주세요.
main()
..
..
Enter a number (<Enter key> to quit) 1
Enter a number (<Enter key> to quit) 3
Enter a number (<Enter key> to quit)
합 4.0
평균값 2.0
표준편차 1.0
중앙값 2.0
데이터의 행렬
데이터의 행렬 변환
A Visual Intro to NumPy and Data Representation
-
소리 데이터의 경우 numpy로 1차원 array로 표현합니다. CD음원파일의 경우, 44.1kHz의 샘플링 레이트로 -32767 ~ 32768의 정수 값을 갖습니다.
-
흑백 이미지의 경우 numpy로 이미지 사이즈의 세로X 가로형태의 행렬(2차원 ndarray)로 나타내고, 각 원소는 픽셀별로 명도(grayscale)를 0~255 의 숫자로 환산하여 표시 합니다. 0은 검정, 255는 흰색입니다.
-
컬러 이미지의 경우 numpy로 이미지 사이즈의 세로 X 가로형태의 행렬에 Red, Green, Blue계열의 3 색으로 행렬을 3개 만듭니다. 따라서 차원은 3차원 입니다.
-
자연어(블로그에서는 Language로 표기)의 경우 numpy로 임베딩(Embedding)이라는 과정을 거쳐 ndarray로 표현될 수 있습니다. 블로그의 예시에서는 71,290개의 단어가 들어있는 (문장들로 이루어진) 데이터셋이 있을때, 이를 단어별로 나누고 0 - 71289로 넘버링 했습니다. 이를 토큰화 과정이라고 합니다. 그리고 이 토큰을 50차원의 word2vec embedding 을 통해 [batch_size, sequence_length, embedding_size]의 ndarray로 표현할 수 있습니다.
이미지의 행렬 변환
아래 이미지는 동일한 사이즈의 이미지에 대해 픽셀이 1 X 1 (1개)일때 부터 100 X 100 (10,000개)일때 이미지의 해상도를 나타내고 있습니다.
이미지는 수많은 점(픽셀)들로 구성되어 있습니다. 각각의 픽셀은 R, G, B 값 3개 요소의 튜플로 색상이 표시됩니다. (Red, Green, Blue의 값이에요)
흰색(W) : (255,255,255) 검정색(B) : (0, 0, 0) 빨간색(R) : (255, 0, 0) 파란색(B) : (0, 0, 255) 녹색(G) : (0, 128, 0) 노란색(Y) : (255, 255, 0) 보라색(P) : (128, 0, 128) 회색(Gray) : (128, 128, 128)
흑백의 경우에는 Gray 스케일로 나타내는데, 0~255 범위의 숫자 1개의 튜플 값이에요. Color는 투명도를 포함하는 A를 포함해 RGBA 4개로 표시하기도 합니다. 아래 그림처럼, Image의 좌표는 보통 왼쪽 위를 (0, 0)으로 표시하고, 오른쪽과 아래로 내려갈수록 좌표가 증가합니다.
이미지와 관련된 파이썬 라이브러리
import PIL
PIL.__version__
..
..
'8.1.0'
-
open : Image.open()
-
size : Image.size
-
filename : Image.filename
-
crop : Image.crop((x0, y0, xt, yt))
-
resize : Image.resize((w,h))
-
save : Image.save()
이미지 저장
$ mkdir -p ~/aiffel/data_represent/image
$ ln -s ~/data/newyork.jpg ~/aiffel/data_represent/image
..
..
from PIL import Image, ImageColor
import os
img_path = os.getenv("HOME") + "/aiffel/data_represent/image/newyork.jpg"
img = Image.open(img_path)
print(img_path)
print(type(img))
img
..
..
img.size
(212, 300)
W, H = img.size
print((W, H)
(212, 300)
print(img.format)
print(img.size)
print(img.mode)
JPEG
(212, 300)
RGB
이미지 자르기
이미지를 자를 때에는 .crop() 메소드를 이용합니다
img.crop((30,30,100,100))
이미지 저장
자른 이미지를 저장해 보도록 하겠습니다.
# 새로운 이미지 파일명
cropped_img_path = os.getenv("HOME") + "/aiffel/data_represent/image/cropped_img.jpg"
img.crop((30,30,100,100)).save(cropped_img_path)
print("저장 완료!")
..
..
저장 완료!
행렬로 변환
이미지 파일 행렬로 변환
import numpy as np
img_arr = np.array(img)
print(type(img))
print(type(img_arr))
print(img_arr.shape)
print(img_arr.ndim)
..
..
<class 'PIL.JpegImagePlugin.JpegImageFile'>
<class 'numpy.ndarray'>
(300, 212, 3)
3
컬러(RGB)이미지 파일이니 변환된 행렬은 Height X Width X RGB Channel의 모양이고 차원 역시 3차원 입니다.
img_arr
array([[[133, 180, 250],
[133, 180, 250],
[133, 180, 250],
...,
[133, 180, 250],
[133, 180, 250],
[133, 180, 250]],
[[133, 180, 250],
[133, 180, 250],
[133, 180, 250],
...,
[133, 180, 250],
[133, 180, 250],
[133, 180, 250]],
[[133, 180, 250],
[133, 180, 250],
[133, 180, 250],
...,
[133, 180, 250],
[133, 180, 250],
[133, 180, 250]],
...,
[[164, 199, 255],
[164, 199, 255],
[164, 199, 255],
...,
[164, 199, 255],
[164, 199, 255],
[164, 199, 255]],
[[164, 199, 255],
[164, 199, 255],
[164, 199, 255],
...,
[164, 199, 255],
[164, 199, 255],
[164, 199, 255]],
[[164, 199, 255],
[164, 199, 255],
[164, 199, 255],
...,
[164, 199, 255],
[164, 199, 255],
[164, 199, 255]]], dtype=uint8)
흑백모드
img_g = Image.open(img_path).convert('L')
img_g
img_g_arr = np.array(img_g)
print(type(img_g_arr))
print(img_g_arr.shape)
print(img_g_arr.ndim)
..
..
<class 'numpy.ndarray'>
(300, 212)
2
흑백이므로 반환된 행렬은 Height X Width, 차원은 2차원 입니다.
img_g_arr
..
..
array([[174, 174, 174, ..., 174, 174, 174],
[174, 174, 174, ..., 174, 174, 174],
[174, 174, 174, ..., 174, 174, 174],
...,
[195, 195, 195, ..., 195, 195, 195],
[195, 195, 195, ..., 195, 195, 195],
[195, 195, 195, ..., 195, 195, 195]], dtype=uint8)
get color
red = ImageColor.getcolor('RED','RGB')
reda = ImageColor.getcolor('red','RGBA')
yellow = ImageColor.getcolor('yellow','RGB')
print(red)
print(reda)
print(yellow)
..
..
(255, 0, 0)
(255, 0, 0, 255)
(255, 255, 0)
딥러닝에서 위와 같은 이미지 조작은 Data augmentation의 경우 많이 사용 됩니다.
구조화된 데이터
pandas
Series
import pandas as pd
ser = pd.Series(['a','b','c',3])
ser
..
..
0 a
1 b
2 c
3 3
dtype: object
ser.values
..
..
array(['a', 'b', 'c', 3], dtype=object)
ser.index
..
..
RangeIndex(start=0, stop=4, step=1)
ser2 = pd.Series(['a', 'b', 'c', 3], index=['i','j','k','h'])
ser2
..
..
i a
j b
k c
h 3
dtype: object
ser2.index = ['Jhon', 'Steve', 'Jack', 'Bob']
ser2
..
..
Jhon a
Steve b
Jack c
Bob 3
dtype: object
ser2.index
..
..
Index(['Jhon', 'Steve', 'Jack', 'Bob'], dtype='object')
Country_PhoneNumber = {'Korea': 82, 'America': 1, 'Swiss': 41, 'Italy': 39, 'Japan': 81, 'China': 86, 'Rusia': 7}
ser3 = pd.Series(Country_PhoneNumber)
ser3
..
..
Korea 82
America 1
Swiss 41
Italy 39
Japan 81
China 86
Rusia 7
dtype: int64
비단 기본 인덱스 뿐 아니라 값이 할당된 인덱스 형태에 대해서 슬라이싱(slicing) 기능을 지원하기도 하기도 하는 등 특징이 있으니 연습해 두세요.
ser3['Italy':]
Italy 39 Japan 81 China 86 Rusia 7 dtype: int64
Series의 Name
ser3.name = 'Country_PhoneNumber'
ser3.index.name = 'Country_Name'
ser3
..
..
Country_Name
Korea 82
America 1
Swiss 41
Italy 39
Japan 81
China 86
Rusia 7
Name: Country_PhoneNumber, dtype: int64
DataFrame
data = {'Region' : ['Korea', 'America', 'Chaina', 'Canada', 'Italy'],
'Sales' : [300, 200, 500, 150, 50],
'Amount' : [90, 80, 100, 30, 10],
'Employee' : [20, 10, 30, 5, 3]
}
s = pd.Series(data)
s
..
..
Region [Korea, America, Chaina, Canada, Italy]
Sales [300, 200, 500, 150, 50]
Amount [90, 80, 100, 30, 10]
Employee [20, 10, 30, 5, 3]
dtype: object
s = pd.DataFrame(data)
s
..
..
Region Sales Amount Employee
0 Korea 300 90 20
1 America 200 80 10
2 Chaina 500 100 30
3 Canada 150 30 5
4 Italy 50 10 3
s.columns
..
..
Index(['Region', 'Sales', 'Amount', 'Employee'], dtype='object')
s.index
..
..
RangeIndex(start=0, stop=5, step=1)
s.index=['one','two','three','four','five']
s.columns = ['a','b','c','d']
s
..
..
a b c d
one Korea 300 90 20
two America 200 80 10
three Chaina 500 100 30
four Canada 150 30 5
five Italy 50 10 3
구조화된 데이터의 표현법
pandas와 함께 EDA 시작하기
통계데이터를 활용해서 데이터의 대푯값과 분산을 구하는 것은 EDA(Exploratory Data Analysis)의 기본이라고 할 수 있습니다.
csv
import pandas as pd
import os
csv_path = os.getenv("HOME") + "/aiffel/data_represent/data/covid19_italy_region.csv"
data = pd.read_csv(csv_path)
data
..
..
SNo Date Country RegionCode RegionName Latitude Longitude HospitalizedPatients IntensiveCarePatients TotalHospitalizedPatients HomeConfinement CurrentPositiveCases NewPositiveCases Recovered Deaths TotalPositiveCases TestsPerformed
0 0 2020-02-24T18:00:00 ITA 13 Abruzzo 42.351222 13.398438 0 0 0 0 0 0 0 0 0 5
1 1 2020-02-24T18:00:00 ITA 17 Basilicata 40.639471 15.805148 0 0 0 0 0 0 0 0 0 0
2 2 2020-02-24T18:00:00 ITA 4 P.A. Bolzano 46.499335 11.356624 0 0 0 0 0 0 0 0 0 1
3 3 2020-02-24T18:00:00 ITA 18 Calabria 38.905976 16.594402 0 0 0 0 0 0 0 0 0 1
4 4 2020-02-24T18:00:00 ITA 15 Campania 40.839566 14.250850 0 0 0 0 0 0 0 0 0 10
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
793 793 2020-04-01T17:00:00 ITA 9 Toscana 43.769231 11.255889 1120 297 1417 3015 4432 259 182 253 4867 36575
794 794 2020-04-01T17:00:00 ITA 4 P.A. Trento 46.068935 11.121231 345 76 421 1062 1483 124 214 173 1870 7675
795 795 2020-04-01T17:00:00 ITA 10 Umbria 43.106758 12.388247 173 45 218 646 864 17 194 37 1095 9080
796 796 2020-04-01T17:00:00 ITA 2 Valle d'Aosta 45.737503 7.320149 85 27 112 428 540 3 32 59 631 1717
797 797 2020-04-01T17:00:00 ITA 5 Veneto 45.434905 12.338452 1718 350 2068 6156 8224 470 902 499 9625 112746
798 rows × 17 columns
data.head()
data.tail()
data.head(3)
data.columns
..
..
Index(['SNo', 'Date', 'Country', 'RegionCode', 'RegionName', 'Latitude',
'Longitude', 'HospitalizedPatients', 'IntensiveCarePatients',
'TotalHospitalizedPatients', 'HomeConfinement', 'CurrentPositiveCases',
'NewPositiveCases', 'Recovered', 'Deaths', 'TotalPositiveCases',
'TestsPerformed'],
dtype='object')
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 798 entries, 0 to 797
Data columns (total 17 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 SNo 798 non-null int64
1 Date 798 non-null object
2 Country 798 non-null object
3 RegionCode 798 non-null int64
4 RegionName 798 non-null object
5 Latitude 798 non-null float64
6 Longitude 798 non-null float64
7 HospitalizedPatients 798 non-null int64
8 IntensiveCarePatients 798 non-null int64
9 TotalHospitalizedPatients 798 non-null int64
10 HomeConfinement 798 non-null int64
11 CurrentPositiveCases 798 non-null int64
12 NewPositiveCases 798 non-null int64
13 Recovered 798 non-null int64
14 Deaths 798 non-null int64
15 TotalPositiveCases 798 non-null int64
16 TestsPerformed 798 non-null int64
dtypes: float64(2), int64(12), object(3)
memory usage: 106.1+ KB
data.describe()
data.isnull().sum()
..
..
SNo 0
Date 0
Country 0
RegionCode 0
RegionName 0
Latitude 0
Longitude 0
HospitalizedPatients 0
IntensiveCarePatients 0
TotalHospitalizedPatients 0
HomeConfinement 0
CurrentPositiveCases 0
NewPositiveCases 0
Recovered 0
Deaths 0
TotalPositiveCases 0
TestsPerformed 0
dtype: int64
data['RegionName'].value_counts()
..
..
Valle d'Aosta 38
P.A. Trento 38
Piemonte 38
Basilicata 38
Umbria 38
Sicilia 38
Veneto 38
Molise 38
P.A. Bolzano 38
Abruzzo 38
Calabria 38
Sardegna 38
Lombardia 38
Marche 38
Campania 38
Friuli Venezia Giulia 38
Lazio 38
Liguria 38
Toscana 38
Emilia-Romagna 38
Puglia 38
Name: RegionName, dtype: int64
data['Country'].value_counts()
..
..
ITA 798
Name: Country, dtype: int64
data['RegionName'].value_counts().sum()
..
..
798
data['Country'].value_counts().sum()
..
..
798
print(data['TotalPositiveCases'].sum())
print(data['TestsPerformed'].sum())
print(data['Deaths'].sum())
print(data['Recovered'].sum())
..
..
1323913
6329867
129817
164154
data.sum()
..
..
SNo 318003
Date 2020-02-24T18:00:002020-02-24T18:00:002020-02-...
Country ITAITAITAITAITAITAITAITAITAITAITAITAITAITAITAI...
RegionCode 8132
RegionName AbruzzoBasilicataP.A. BolzanoCalabriaCampaniaE...
Latitude 34350.941591
Longitude 9756.312476
HospitalizedPatients 425381
IntensiveCarePatients 65912
TotalHospitalizedPatients 491293
HomeConfinement 538649
CurrentPositiveCases 1029942
NewPositiveCases 110566
Recovered 164154
Deaths 129817
TotalPositiveCases 1323913
TestsPerformed 6329867
dtype: object
print(data['TestsPerformed'].corr(data['TotalPositiveCases']))
print(data['TestsPerformed'].corr(data['Deaths']))
print(data['TotalPositiveCases'].corr(data['Deaths']))
data.corr()
..
..
0.8555291657820235
0.7612209669865387
0.975268668316802
data.drop(['Latitude','Longitude','Country','Date','HospitalizedPatients', 'IntensiveCarePatients', 'TotalHospitalizedPatients','HomeConfinement','RegionCode','SNo'], axis=1, inplace=True)
data.corr()
pandas 통계 관련 메소드
이상으로 pandas에서 제공하는 통계 관련 메소드를 정리했으니 한번 확인해 보세요.
-
count(): NA를 제외한 수를 반환합니다.
-
describe(): 요약통계를 계산합니다.
-
min(), max(): 최소, 최댓값을 계산합니다.
-
sum(): 합을 계산합니다.
-
mean(): 평균을 계산합니다.
-
median(): 중앙값을 계산합니다.
-
var(): 분산을 계산합니다.
-
std(): 표준편차를 계산합니다.
-
argmin(), argmax(): 최소, 최댓값을 가지고 있는 값을 반환 합니다.
-
idxmin(), idxmax(): 최소, 최댓값을 가지고 있는 인덱스를 반환합니다.
-
cumsum(): 누적 합을 계산합니다.
-
pct_change(): 퍼센트 변화율을 계산합니다.
Leave a comment