목차


이번 장에서 다루는 자료 구조는 굉장히 중요한 내용입니다. 자료 구조에 따라 쓸 수 있는 메서드와 함수가 다르기 때문에 후에 진행할 데이터 전처리 하는데 있어서 자료 구조에 대해 지식이 부족한 것은 설계도나 기초 공사 없이 건물을 짓는 것과도 같습니다.



자료 구조


자료 구조는 컴퓨터 과학에서 효율적인 접근 및 수정을 가능케 하는 자료의 조직, 관리, 저장을 의미한다. 더 정확히 말해, 자료 구조는 데이터 값의 모임, 또 데이터 간의 관계, 그리고 데이터에 적용할 수 있는 함수나 명령을 의미한다.

Wegner, Peter; Reilly, Edwin D. (2003/08/29). 《Encyclopedia of Computer Science》. Chichester, UK: John Wiley and Sons.


자료 구조(Data Structure)는 자료 형(Data Type)과는 다른 개념으로 보통 데이터 값의 모임을 말합니다. Python의 자료 구조 중에서 가장 기본적인 리스트(list)부터 시작하겠습니다.


리스트

1. R에서의 벡터와 개념이 유사.

2. 여러 개 원소를 담을 수 있는 1차원 형식 자료

3. 리스트 안에 리스트 삽입 가능

4. 서로 다른 데이터 타입 입력가능

    (R의 벡터와의 차이점)


​1) 생성

L1 = [1,2,3]

L2 = [1,'2',3]    - 4 특성

L3 = [1,2,[3,4]]  - 3 특성

2) 색인

위 변수 L1을 이용하여 리스트 색인을 진행해보겠습니다.

예제 설명
L1[0] 정수(위치) 색인가능
L1[0:2] 슬라이스 색인 가능
L1[[0,2]] 리스트 색인시 여러 개 묶어서 출력 불가
L1[1:] 2부터 ~ 끝까지 색인
L1[:2] [1,2]
L1[::2] start : end : by, 왼쪽처럼 by값만 전달하는 것도 가능

  • 리버스(reverse) 색인 : R과는 다르게 음수 위치값 사용시 끝에서부터 역순으로 색인 시도

    L1[-1] = 3 = L[2]

3) 수정

리스트 안의 원소를 원하는 값으로 수정하는 방법입니다.

L1[0] = 10;

L1
Out : [10, 2, 3]

L1[1] = [20,30] ;

L1
Out : [10, [20, 30], 3]
​​
L1[1:3] = [20,30] ;

L1
Out : [10, 20, 30]
​​

4) 확장 (append 메소드 사용)

  1. append 메소드 사용
L1.append(40) ;

L1
Out[31]: [10, 20, 30, 40]

​​

R에서는 c(L1, 40) / append(L1, 40)

  1. 산술 연산자 이용한 원소 추가
L1 + [4] -  리스트 원소 추가
​​
  1. extend 메소드 사용
L1.extend([5]) - 원소 추가(즉시 반영)
​​

※ 주의 : 기존 리스트의 범위를 벗어나는 경우 값 할당 불가(out of range)

4-2) 확장(+)

L1 = [1,2,3]

L2 = [4,5,6]

L1 + L2 
Out : [1,2,3,4,5,6]
​​
L1 * 3
Out : [1,2,3,1,2,3,1,2,3]
​​

5) 삭제

  1. 특정 위치 원소 제거

    R에서는 중간의 원소를 삭제할 수 없었던 것이 python에서는 가능합니다.

    del(L1[3]) : 4번째 원소 삭제

  2. 변수 제거

    ​del(L1)

  3. 모든 원소 제거 (빈 리스트)

    L1 = []

Python에서는 기본적으로 각 원소별로 계산을 하는 벡터연산이 지원되지 않습니다. 그렇기 때문에 각 원소별로 연산을 처리하기 위해서는 map함수를 사용하면 됩니다.

map 함수의 문법은 map(함수, 변수)인데 자신이 원하는 함수를 사용하기 위해서 함수 만들기에 대해 설명드리겠습니다.

함수 만들기

  1. 사용자 정의 함수 만들기

    아래 코드에서 function 에는 함수 이름을 적고 괄호 안에는 사용할 변수를 지정 후 만드는 것으로, R에서 만들었던 그 사용자 정의 함수와 언어적인 차이를 제외하면 거의 비슷합니다.


def function(x,y):
    if x == 0 :
        break
    else :
        pass
    return x + y


    2. 람다(lambda) 함수 (간편 사용자 정의 함수)

사용자 정의 함수보다 사용하기 편리한 람다 함수가 있습니다. lambda를 선언하고 들어갈 원소의 이름을 임의로 설정 후 : 뒤에는 앞에서 선정한 원소가 들어갔을 때 적용시킬 수식을 적으면 됩니다.

- 리스트에 원소별로 연산

f1 = lambda x : x * 1.1

list(map(f1,L1))

map 함수 사용시 주의할 점이 있는데 타입을 정해주지 않으면 결과값이 정상적으로 출력되지 않습니다. 위에서도 정상적인 결과값 출력을 위해 map에 list를 추가로 적었습니다.


시리즈

시리즈(Series)는 리스트와 비슷한 1차원 형식의 데이터 구조로 모듈 pandas에 내장되어 있으며 기존 python의 리스트(list)보다 색인시 유리합니다. 그래서 list에서 원하는 자료를 찾고 싶을때 Series로 치환 후 색인, 그리고 다시 list로 재치환하는 경우도 있다고 합니다.

||리스트|시리즈|

  • |-|- 형태|L1 = [1,2,3,4,5]|s1 = Series([1,2,3,4,5]) 벡터 색인|L1[[1, 3]] |s1[[1,3]] .||1 2
    3 4 조건 전달 및 색인|L1[ L1 > 2]|s1[s1 > 2] .||2 3
    3 4
    4 5 ​
리스트에서 안되는 색인이 가능한 시리즈


시리즈 불러오기

from pandas import Series

​from 모듈명 import 함수명의 방식으로 함수를 불러오면 함수를 사용할때마다 모듈.을 함수 앞에 붙이지 않아도 되어 코드가 간편해진다는 장점이 있습니다.

s1 = Series([1,2,3,4,5]);

s1
Out :               

0 1
1 2
2 3
3 4
4 5
dtype: int64

출력 결과를 살펴보면 먼저 시리즈의 위치 값/데이터 값을 가르키고, dtype은 데이터 타입을 의미합니다.


튜플(tuple)

튜플은 리스트와 동일한 1차원 자료구조로 서로 다른 데이터 타입 허용을 한다는 공통점이 있습니다. 하지만 원소의 개별적인 수정이 되지 않는다는 차이점이 있습니다. 그렇기 때문에 수정이 되면 안되는 참조용 자료 생성시 쓰이며, 수정 관련 외 나머지 특성은 리스트와 동일합니다.

  1. 생성
t1 = (1,2,3) ; t1
Out : (1,2,3)

딕셔너리

딕셔너리(Dictionary)는 [key - value] 구조라는 점에서 R의 리스트와 비슷합니다. Series와 Dataframe의 기본 구조가 되는 데이터 구조입니다.

1. 생성

딕셔너리 생성은 다음과 같이 중괄호 안에 'key' : value 방식으로 값들을 넣어주면 됩니다.

d1 = {'a':1, 'b':2}

2. 색인

딕셔너리에서의 색인은 key 를 입력하면 value를 찾아주는 방식입니다.

d1['a']   /   d1.get('a')
Out : 1

3. 수정

딕셔너리에서는 key 값에 value를 넣어줌으로서 수정/추가가 가능합니다. 삭제 또한 key를 지정하여 del함수로 제거함으로서 가능합니다.

   d1['b'] = 22 ; d1
   Out : {'a': 1, 'b': 22}

   d1['c'] = 3  ; d1
   Out : {'a': 1, 'b': 22, 'c': 3}

   del(d1['c']) ; d1
   Out : {'a': 1, 'b': 22}
​​




반복문

프로그래밍에서 특정 코드가 일정 범위내에서 반복하게 해주는 것을 반복문(iteration)이라고 합니다. 반복문 중에는 for문while문이 있습니다.

for문

for i in range(start 값 ,end 값, 단위값) : ​ 지정한 범위 내에서 순서대로 i에 값을 입력하고 반복문 내에서 이를 일시적으로 변수로 사용합니다. 예를 들어 for i in range(0,3):라는 반복문이 있으면 다음 과정을 거치며 반복이 됩니다.

  1. i에 0을 넣고 반복문 내에 있는 i에 0을 입력합니다.
  2. 반복문 내의 코드 실행이 끝나면 다시 처음으로 돌아가 i에 1을 넣고 반복문 내에 있는 i에 1을 입력합니다.
  3. 마찬가지로 코드 실행이 끝나면 다시 처음으로 돌아가 i에 2를 넣고 반복문 내에 있는 i에 2를 입력합니다.
  4. 코드 실행이 마치면 반복문이 끝납니다.

예시를 보면서 다시 for문을 살펴봅시다.

for i in range(0,3):
    print(i)
0
1
2

- range 괄호 안에서 단위값은 생략이 가능(기본값 1)

- range() 자리에는 리스트를 넣을 수 있습니다.

  for i in L1 : ...

while문

while 문은 for 문과 다르게 초깃값을 설정하는 것이 중요합니다. 반복하는 범위를 처음에 정하는 것이 아니라 특정 조건을 만족할 때까지 반복문이 실행되기 때문에 조건에 들어가는 변수가 끝맺을 수 있도록 해주는 것이 중요합니다. 예를 들어 i가 False가 될 때 까지 while문을 실행하는 조건을 걸었는데 i가 True에서 변화가 없다면 끝없이 무한히 반복할 것 입니다.

[예시] 1부터 10까지 출력

i = 1
while i < 11 :
    print(i)
    i = i + 1

if문

if/else 문은 for, while문이 특정 조건에서만 실행하도록 합니다. 문법은 아래와 같습니다.

for i in range(...) :
    if _조건_ :
        ...
    else :
        ....

제어문

break

: break가 속하는 for문을 중단합니다. 실행하는 실행문을 모두 중단하는 것이 아니라 for문 하나만 빠져나오는 것입니다.

for i in range(0,10):
    if i > 5:
        break
    print(i)
print('print!!')
0
1
2
3
4
5
print!!
i가 5보다 커진 이후 for문은 탈출했으나 마지막 print함수는 실행

continue

: continue 아래의 일부 코드를 실행시키지 않고 바로 루프를 돌리게 합니다. break문보다 살짝 약하다고 생각하시면 됩니다.

for i in range(0,10):
    if i % 2 == 1:
        continue
    print(i)
2
4
6
8
조건에 일치하지 않을 경우 다음 for문으로 이동

pass

: 해당 조건에서 아무 일도 일어나지 않게 하기 위해 사용합니다. 에러가 날 때 에러 메시지를 출력하는 대신 어떠한 출력도 원하지 않을 경우 사용하기도 합니다.

리스트 내포 표현식

  • 리스트 내포 표현식(List Comprehension)은 리스트가 벡터 연산이 안되는 점을 map함수보다도 간단한 문법으로 가능하게 합니다.

  • 리스트 내부에 반복문/조건문의 축약형 형태 전달이 가능합니다.

  • 또 하나 장점으로 같은 구문의 경우 for문에 비해 성능이 좋습니다.(속도가 빠릅니다.)

표현식 문법

  1. [리턴값 for i in 대상]

  2. [리턴값 for i in 대상 if 조건]

  3. [True시 리턴값 if 조건 else F리턴값 for i in 대상]

아래 예시를 통해 리스트 내포 표현식을 정복해봅시다.

예시1 ) L1 = [1,2,3,4,5]에서 10% 인상된 값 리턴

이름 문법
for문 L2 = []
for i in range(0,len(L1)):
   L2.append(L1[i] * 1.1)
map list(map(lambda x : x * 1.1, L1))
리스트 내포 표현식 [i * 1.1 for i in L1]


예제 2) 리스트 L1에서 3보다 작은 값만 출력

이름 문법
for문 L2 = []
for i in L1:
    if i < 3 :
        L2.append(i)
map list(map(lambda x :
x if x < 3 else None, L1))
리스트 내포 표현식 [i for i in L1 if i < 3]


여기까지 기본적으로 사용하는 자료 구조와 반복문에 대해 알아보았습니다. 다음 포스트는 지역/전역 변수, 파일 입출력같은 개념까지 다루면서 Part 1을 마치며 Part 2부터는 numpy 모듈부터 다루도록 하겠습니다.



다음 글

  • 딥 카피
  • 지역 변수 / 전역 변수
  • 매개변수 전달방식
  • 모듈 생성 및 패키지
  • 파일 입/출력