본문 바로가기

Geo Data

[Geo Data] 서울대학교·LH 도시 데이터분석 학교 1일차

- 데이터 분석 기본 라이브러리 numpy, pandas에 대해 살펴봄.

 

 

1. 기본 라이브러리 학습

1.1. numpy

numpy는 array(배열) 프로그래밍을 지원하는 패키지이며, 속도가 느리고 메모리를 많이 차지하는 list에 비해 빠른 연산속도를 자랑한다. numpy는 벡터, 행렬 등을 지원하여 선형대수 계산에 주로 사용되며, 이는 많은 머신러닝 패키지 (scikit-learn 등), 딥러닝 패키지 (tensorflow 등)의 근간이 된다.

numpy array의 이해

import numpy as np
# numpy array는 np.array를 통해 만들 수 있다.

a = np.array([1,2,3,4])
print(a)
print(type(a))
print(len(a))
print(a.shape)

>>> [1 2 3 4]
>>> # <class 'numpy.ndarray'>
>>> 4
>>> (4,)

# array는 원소들이 모두 같은 자료형이어야 한다. 숫자 array에 문자를 넣으면 숫자가 문자 자료형으로 바뀜.
b = np.array(['딸기', '당근', '수박', '참외'])
c = np.append(a,b)
print(c)
print(type(c[1]))
print(type(a[1]))

>>> ['1' '2' '3' '4' '딸기' '당근' '수박' '참외']
>>> # <class 'numpy.str_'>
>>> # <class 'numpy.int32'>

#array의 성분은 모두 index를 가지고 있다. 이를 이요해서 성분을 바꿀 수 있다.
print(a[0], a[1])
a[0] = 5 # array의 가장 첫 번째 성분을 5로 변경
print(a)

>>> 1 2
>>> [5 2 3 4]

# array의 슬라이싱을 이용하여 부분을 추출할 수 있다.
print(c[1:5])
print(c[:5])
print(c[5:])

>>> ['2' '3' '4' '딸기']
>>> ['1' '2' '3' '4' '딸기']
>>> ['당근' '수박' '참외']

# np.append를 통해 array를 이어붙일 수 있다.
d = np.array([5,6])
e = np.append(a, d)
print(e)

>>> [5 2 3 4 5 6]

# np.arange를 통해 순차적인 1차원 행렬을 생성할 수 있다.
print(np.arange(10))
print(np.arange(8,12))    #2개를 넣읗 경우 (시작, 끝-1)
print(np.arange(5,12,2))  #3개를 넣읗 경우 (시작, 끝-1,간격)

>>> [0 1 2 3 4 5 6 7 8 9]
>>> [ 8  9 10 11]
>>> [ 5  7  9 11]

array의 연산

array는 원소끼리의 덧셈, 뺄셈을 수행하는 연산 방식을 채택하여, 수열, 행렬 연산에 활욯할 때 편리하며, 뒤에서 배울 pandas 데이터 역시 이러한 연산방식을 채택하고 있다.

a = np.array([1,2,3])
b = np.array([2,5,6])
c = [10,20,30]

# Python의 기본 연산자에 대해서 원소끼리 연산한 결과가 나옵니다.
print(a + b)  #원소끼리 더함
print(a - b)  #원소끼리 뺌
print(a * b)  #원소끼리 곱함
print(b / a)  #원소끼리 나눔
print(b // a)
print(b % a)
print(a ** b)
print(a + b * c)

>>> [3 7 9]
>>> [-1 -3 -3]
>>> [ 2 10 18]
>>> [2.  2.5 2. ]
>>> [2 2 2]
>>> [0 1 0]
>>> [  1  32 729]
>>> [ 21 102 183]

다차원 array

# array는 1차원 뿐만 아니라 2차원, 3차원... n차원 등 다차원 행렬도 만들 수 있다.

#2차원 행렬
a2 = np.array([[1,2,3],[4,5,6]])
print(a2)
print(type(a2))

#3차원 행렬
a3 = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])
print(a3)
print(type(a3))


>>> [[1 2 3]
>>>  [4 5 6]]
>>> # <class 'numpy.ndarray'>


>>> [[[1 2]
>>>   [3 4]]

>>> [[5 6]
>>>  [7 8]]]
>>> # <class 'numpy.ndarray'>
#dim 속성을 이용하여 array의 차원 수를 알 수 있다.
print(a.ndim)
print(a2.ndim)
print(a3.ndim)

#shape 속성을 이용하여 array의 크기 (몇 곱하기 몇인지)를 알 수 있다.
print(a.shape)
print(a2.shape)
print(a3.shape)

>>> 1
>>> 2
>>> 3
>>> (3,)		# 1행 3열
>>> (2, 3)	# 3행 2열
>>> (2, 2, 2)
#T 속성을 사용하면 행렬을 변환할 수 있다.
a2.T

>>> array([[1, 4],
>>>        [2, 5],
>>>        [3, 6]])		# 2열 3행

 

 

다차원의 이해

다차원 array의 indexing과 slicing

a2 = np.array([[1,2,3],[4,5,6]])
print(a2)

>>> [[1 2 3]
>>>  [4 5 6]]

print('indexing 1')
print(a2[0,0]) # a 행렬의 (1,1) 성분
print(a2[1,2]) # a 행렬의 (2,3) 성분

>>> indexing 1
>>> 1
>>> 6

print('indexing 2')
print(a2[0,:]) # a 행렬의 첫 번째 행
print(a2[:,2]) # a 행렬의 세 번째 열
print(a2[:,-1]) # a 행렬의 마지막 열

>>> indexing 2
>>> [1 2 3]
>>> [3 6]
>>> [3 6]

print('slicing')
print(a2[0:2,2]) # a 행렬 1~2행, 2열 원소 추출

>>> slicing
>>> [3 6]

array의 기술 통계

data = np.arange(5,15,2)
print(data)

>>> [5, 7, 9, 11, 13]

print(data.sum())   #합
print(data.prod())   #곱
print(data.mean())   #평균
print(data.std())   #표준편차
print(data.min())   #최댓값
print(data.max())   #최솟값

>>> 45
>>> 45045
>>> 9.0
>>> 2.8284271247461903
>>> 5
>>> 13

#사분위수
print('percentile')
print(np.percentile(data, 25))  # 1사분위 수
print(np.percentile(data, 50))  # 2사분위 수 (중간값)
print(np.percentile(data, 75))  # 3사분위 수

>>> percentile
>>> 7.0
>>> 9.0
>>> 11.0

# 각 명령어의 괄호 안에 axis parameter를 추가하여 행, 열 별로 계산할 수 있습니다
x = np.array([[1,2, 3],[4,5,6]])
print(x)
print("vertical sum, axis=0", x.sum(axis=0))
print("horizontal sum, axis=1", x.sum(axis=1))

>>> [[1 2 3]
>>>  [4 5 6]]
>>> vertical sum, aixs=0 [5 7 9]
>>> horizontal sum, axis=1 [ 6 15]

1.2. pandas

pandas는 열과 행으로 이루어져 있는 Table을 처리하고 가공하는 라이브러리로, Python으로 데이터를 다룰 때, 빠질 수 없는 아주 중요한 패키지이다. DataFrame이라는 표 형태의 자료형을 제공하며, 여기에 데이터를 담아 원하는 형태로 추출, 변환, 집계, 병합 등이 가능하다.|

pandas dataframe

pandas에는 한 열로 구성된 1차원 형태의 Series, 열들이 모여 Table을 이루는 DataFrame, 2가지 자료형으로 구성되어 있다.

Series

먼저 series는 데이터의 순서와 값들을 나열한 자료형으로, Table의 열 하나가 series이다. 선언은 다음과 같이 할 수 있다.

# Series는 1차원 배열로 실제 값들이 나열되어 있는 Value와 이러한 값들에 번호를 매기는 Index로 구성되어 있습니다.
# index가 따로 지정되지 않으면, 자동으로 0부터 순차적으로 지정됩니다
a = [1,2,3,4,5]
a_series = pd.Series(a)
print(a)
print(a_series)

>>> [1, 2, 3, 4, 5]
>>> 0    1
>>> 1    2
>>> 2    3
>>> 3    4
>>> 4    5
>>> dtype: int64

# 인덱스 지정
b = [6,7,8,9,10]
b_index = ['a', 'b', 'c', 'd', 'e']
b_series = pd.Series(b, index=b_index)
print(b)
print(b_series)

>>> [6, 7, 8, 9, 10]
>>> a	6
>>> b	7
>>> c	8
>>> d	9
>>> e	10
>>> dtype: int64

# array와 마찬가지로 대괄호 안에 Index 값을 넣어 특정 값만 추출할 수 있습니다
print(a_series[2])
print(b_series['b'])

>>> 3
>>> 7

DataFrame

# DataFrame은 2치원 형태의 자료구조이며, 행은 Index 번호로, 열은 column 이름으로 구분한다.
raw_data = {'col0': [1,2,3,4,5],
           'col1': [10,20,30,40,50],
           'col2': [100,200,300,400,500]}    
df = pd.DataFrame(raw_data)
df

>>>		 col0	col1	col2
>>>	0	1	10	100
>>>	1	2	20	200
>>>	2	3	30	300
>>>	3	4	40	400
>>>	4	5	50	500

print(a_series.shape)    #series는 1차원
print(df.shape)    #DataFrame은 2차원

>>> (5,)
>>> (5,3)

# DataFrame의 각 열은 Series가 됩니다.
# DataFrame에서 Series만 추가하는 방식은 대괄호 방식, 속성 추출방식이 있습니다.
print(df['col0'])
print(df.col1)
print(type(df))
print(type(df.col1))

>>> 0    1
>>> 1    2
>>> 2    3
>>> 3    4
>>> 4    5
>>> # Name: col0, dtype: int64
>>> 0    10
>>> 1    20
>>> 2    30
>>> 3    40
>>> 4    50
>>> # Name: col1, dtype: int64
>>> # <class 'pandas.core.frame.DataFrame'>
>>> # <class 'pandas.core.series.Series'>

Dataframe 열 추가 및 제거

# Dataframe에 열을 추가할 수 있습니다.
new=['딸기', '당근', '수박', '참외', '메론']
df['new_column'] = new
df['new_column2'] = 10
df['new_column3'] = np.nan  #결측치
df

# 이하 데이터 프레임의 출력값은 생략하도록한다.
더보기

열 이름은 영어, 한글, 띄어쓰기, 숫자 모두 포함 가능하나, 되도록 다음과 같은 규칙을 지키시오!

- 한글, 띄어쓰기, 특수문자는 지양하고, 영어, 숫자, 언더바(_)로 구성한다
- 너무 길게 하지 않으면서 어떤 정보인지 알 수 있게 한다.
good : people_old, energy_2018, hnd_nm

bad : 노인인구, (최종)_2018!, hnd code

#열 삭제1 : del 명렁어로 열을 삭제할 수 있다
del df['new_column3']
df

#열 삭제2 : drop 명렁어도 가능하며 열을 제외할때는 axis=1 명시
df.drop(columns = ['new_column2'])    #단 drop한 결과를 저장할 때에는 새로 변수 선언, 대입 필요

** loc, iloc을 통한 부분 추출 ** (중요!!)
Dataframe은 loc 명령어를 통해 인덱싱, 슬라이싱을 할 수 있습니다.

# loc 명령어를 통해 DataFrame의 특정 행, 특정 열을 추출할 수 있습니다
df.loc[1:3,:] #특정 행과 모든 열 (인덱스 1~3 행)

df.loc[:,['col0','new_column']] #특정 열과 모든 행	('col0'열과 'new_column'열)

df.loc[:,['new_column', 'new_column2', 'col0']] # 컬럼 순서 변경할 때 사용 가능

df.loc[3:5,['col1','new_column']]  #특정 열과 특정 행 (인덱스 3~5행, 'col1'와'new_column'열)

df.loc[[1,2,4],['col1','new_column']] #특정 열과 특정 행 (인덱스 1,2,4행, 'col1'와'new_column'열)

df.iloc[[1,3],[2,4]]      #iloc은 실제 배열 순서로 추출하며, 열의 이름 대신 위치를 숫자로 입력 가능
(1,3번째 행, 2,4번째 열)

df.T   #행, 열 전치