728x90
반응형

 지난 포스트에서 기초적인 파이썬 코드를 사용하여, 퍼셉트론을 구현해보았다. 이번 포스트에서는 지난번에 생성한 퍼셉트론을 사용해서 논리 회로를 적용해보겠다.

 

 

논리회로(Logical circuit)

 1937년 클로드 섀넌(Claude Shannon)이 개발한 논리 회로(Logical Circuit)는 불 대수(Boolean algebra)를 물리적으로 구현한 것으로, 하나 이상의 논리적 입력값(True / False)이 들어가면, 그에 맞는 논리 연산(And / Or 등)을 수행하여 하나의 논리적 출력 값(True / False)을 얻는 전자 회로다.

 논리 회로는 다양한 불 대수의 조합을 통해 다양한 기능을 수행할 수 있는데, 이를 이용해서 컴퓨터 같은 고등 연산이 가능한 기계를 만들어 낼 수도 있다.

 여기서 AND, NOT, OR, XOR 등과 같은 기본이 되는 논리 연산을 수행하는 것을 논리 게이트(Logical gate)라 한다.

 만약, 앞에서 만들었던 퍼셉트론이 논리 게이트에 대해서도 적용 가능하다면, 퍼셉트론을 이용해서 컴퓨터도 만들 수 있지 않을까?

 

 

 

논리 게이트

1. AND 게이트

  • AND 게이트는 우리가 코드를 짤 때, 익숙한 논리 연산자 AND와 같으며, 이는 집합에서 교집합에 해당한다. 교집합은 두 집합이 모두 참(True)일 경우, 참(True)을 반환하는 것이다.
  • 두 집합에 대한 진리표를 만들어, 이를 보다 쉽게 이해해보자.
$x_1$ $x_2$ $y$
0 0 0
0 1 0
1 0 0
1 1 1
  • 위 표를 볼 때, 1은 True(참)이라 생각하고, 0은 False(거짓)이라고 생각해보자.
  • 위 표를 퍼셉트론의 공식에 맞게 고쳐보자.

$$ y = \begin{cases}
 0, \ \ \ w_1*0 + w_2*0 \leq \theta \\ 
 0, \ \ \ w_1*0 + w_2*1 \leq \theta \\ 
 0, \ \ \ w_1*1 + w_2*0 \leq \theta \\ 
 1, \ \ \ w_1*1 + w_2*1 > \theta  
\end{cases} $$

  • 위 공식을 보면, 변수인 가중치($w_1, w_2$)와 임계값($\theta$)을 어떻게 설정하느냐로 AND 게이트를 구현할 수 있다는 것을 알 수 있다.
  • 위 공식을 참으로 만드는 가중치와 임계값을 설정하여, AND 게이트를 구현해보자
# Perceptron
>>> def Perceptron(x1, x2, w1, w2, theta):
    
>>>     y = w1*x1 + w2*x2
    
>>>     if y <= theta:
>>>         return 0
>>>     elif y > theta:
>>>         return 1
    
    
# AND Gate를 구현해보자.
>>> w1, w2, theta = 0.5, 0.5, 0.8

>>> print("AND Gate")
>>> print("----"*20)
>>> print("(0, 0):", Perceptron(x1=0, x2=0, w1=w1, w2=w2, theta=theta))
>>> print("(0, 1):", Perceptron(x1=0, x2=1, w1=w1, w2=w2, theta=theta))
>>> print("(1, 0):", Perceptron(x1=1, x2=0, w1=w1, w2=w2, theta=theta))
>>> print("(1, 1):", Perceptron(x1=1, x2=1, w1=w1, w2=w2, theta=theta))

AND Gate
--------------------------------------------------------------------------------
(0, 0): 0
(0, 1): 0
(1, 0): 0
(1, 1): 1
  • 위 코드를 보면, 가중치와 임계값을 0.5로 정했을 뿐인데, AND Gate와 동일한 결과가 나온 것을 알 수 있다.

 

 

 

2. NAND 게이트

  • 이번에는 AND 게이트의 반대인 NOT AND 게이트인 NAND 게이트를 구현해보자.
  • NAND 게이트는 AND 게이트의 반대이므로, 진리표는 다음과 같다.
$x_1$ $x_2$ $y$
0 0 1
0 1 1
1 0 1
1 1 0
# NAND Gate를 구현해보자.
>>> w1, w2, theta = -0.5, -0.5, -0.8

>>> print("NAND Gate")
>>> print("----"*20)
>>> print("(0, 0):", Perceptron(x1=0, x2=0, w1=w1, w2=w2, theta=theta))
>>> print("(0, 1):", Perceptron(x1=0, x2=1, w1=w1, w2=w2, theta=theta))
>>> print("(1, 0):", Perceptron(x1=1, x2=0, w1=w1, w2=w2, theta=theta))
>>> print("(1, 1):", Perceptron(x1=1, x2=1, w1=w1, w2=w2, theta=theta))

NAND Gate
--------------------------------------------------------------------------------
(0, 0): 1
(0, 1): 1
(1, 0): 1
(1, 1): 0
  • NAND Gate는 AND Gate의 반대이므로, 가중치와 임계값을 모두 역수로 만들어주었다.

 

 

 

3. OR 게이트

  • 다음은 또 다른 기본 논리 게이트 중 하나인 OR 게이트를 구현해보자.
  • OR은 집합의 합집합에 해당하며, 둘 중 하나라도 True인 경우 True를 반환한다.
$x_1$ $x_2$ $y$
0 0 0
0 1 1
1 0 1
1 1 1
# OR Gate를 구현해보자.
>>> w1, w2, theta = 0.5, 0.5, 0.2

>>> print("OR Gate")
>>> print("----"*20)
>>> print("(0, 0):", Perceptron(x1=0, x2=0, w1=w1, w2=w2, theta=theta))
>>> print("(0, 1):", Perceptron(x1=0, x2=1, w1=w1, w2=w2, theta=theta))
>>> print("(1, 0):", Perceptron(x1=1, x2=0, w1=w1, w2=w2, theta=theta))
>>> print("(1, 1):", Perceptron(x1=1, x2=1, w1=w1, w2=w2, theta=theta))

OR Gate
--------------------------------------------------------------------------------
(0, 0): 0
(0, 1): 1
(1, 0): 1
(1, 1): 1
  • OR 게이트도 오로지 가중치만 바꾸었는데, 우리가 원하는 값을 반환한 것을 볼 수 있다!

 

 

 

4. 퍼셉트론 공식 정리 및 코드 체계화

  • 지금까지 퍼셉트론 코드를 짜보며, 이 코드를 보다 쉽게 바꿀 수 있다는 생각이 들지 않는가?
  • 먼저 퍼셉트론에 사용된 공식에서 임계값 $\theta$를 왼쪽으로 이동시켜, 절편으로 만들면 어떨까?

$$ y = \begin{cases}
 0, \ \ \  (w_1x_1 + w_2x_2 + b \leq 0)  \\ 
 1, \ \ \  (w_1x_1 + w_2x_2 + b > 0) 
\end{cases} $$

  • 좌변으로 이동하면서 $-\theta$로 부호가 음수로 바뀌었는데, 보기에 깔끔하지 않으니 부호가 양수인 $b$라는 절편으로 만들어보았다.
  • 그런데 위 공식을 보면, 어디서 많이 본 공식과 굉장히 유사하지 않은가? 그렇다. 회귀식과 퍼셉트론의 공식은 동일하며, 이로써 퍼셉트론도 선형성을 따지는 것임을 알 수 있다.
  • 위 내용을 코드에 반영하면서, 동시에 퍼셉트론으로 AND 게이트, NAND 게이트, OR 게이트를 구현할 때, 오로지 가중치만을 바꿨는데, 이를 보다 깔끔한 코드로 구현해보자.
>>> class Logical_gate:
    
>>>     def __init__(self, weight_dict):
        
>>>         self.weight = weight_dict


>>>     def Perceptron(self, x1, x2, key):

>>>         weight = self.weight[key]
>>>         w = weight["w"]
>>>         b = weight["b"]

>>>         y = w[0]*x1 + w[1]*x2 + b

>>>         if y <= 0:
>>>             return 0
>>>         elif y > 0:
>>>             return 1
        
>>>     def Run_Gate(self, key):

>>>         print(key + " Gate")
>>>         print("----"*20)
>>>         print("(0, 0):", self.Perceptron(0, 0, key))
>>>         print("(0, 1):", self.Perceptron(0, 1, key))
>>>         print("(1, 0):", self.Perceptron(1, 0, key))
>>>         print("(1, 1):", self.Perceptron(1, 1, key))
>>>         print("----"*20)
>>>         print("\n")
>>> weight_dict = {"AND":{"w":[0.5,0.5], "b":-0.5},
>>>                     "NAND":{"w":[-0.5,-0.5], "b":0.5},
>>>                     "OR":{"w":[0.5,0.5], "b":-0.2}}

>>> LG = Logical_gate()

>>> LG.Run_Gate("AND")
>>> LG.Run_Gate("NAND")
>>> LG.Run_Gate("OR")

AND Gate
--------------------------------------------------------------------------------
(0, 0): 0
(0, 1): 0
(1, 0): 0
(1, 1): 1
--------------------------------------------------------------------------------


NAND Gate
--------------------------------------------------------------------------------
(0, 0): 1
(0, 1): 0
(1, 0): 0
(1, 1): 0
--------------------------------------------------------------------------------


OR Gate
--------------------------------------------------------------------------------
(0, 0): 0
(0, 1): 1
(1, 0): 1
(1, 1): 1
--------------------------------------------------------------------------------
  • 위 코드는 기존의 퍼셉트론 코드에 비해 더 어려워 보이긴 하지만, 일단 만들어 놓으면, 사용하기는 훨씬 쉽다.
  • 새로운 논리 게이트를 구현하고자 하면, 딕셔너리인 weight_dict에 새로운 가중치($w_1, w_2, b$ 모두를 앞으로 단순하게 가중치로 부르겠다.)만 담으면 끝이다.

 

 

 

 지금까지 퍼셉트론을 이용해서 AND, NAND, OR 게이트를 가중치만 바꿔서 구현한 것을 살펴보았는데, 지금까지만 보면, 퍼셉트론이 논리 게이트에서도 잘 작동하는 것으로 보일 것이다.

 그러나, 앞서 말했듯 퍼셉트론도 선형성을 기반으로 결과를 도출하고, 그 결과가 활성화 함수인 계단 함수(이 부분은 뒤에서 자세히 다루겠다.)를 통해 출력되었는데, 이에 대한 반례가 존재한다.

 다음 포스트에서는 퍼셉트론의 논리 게이트 적용에서 반례인 XOR 게이트에 대해 학습해보고, 어째서 그런 문제가 발생하는지, 그리고 해결 방안은 무엇인지에 대해 학습해 보겠다.

728x90
반응형
728x90
반응형

 지난 포스트의 머신러닝, 딥러닝에 대한 설명이 잘 와 닿지 않았을 수 있다. 그러나 퍼셉트론(Perceptron)에 대해 학습해보면, 어떤 과정을 통해서 머신러닝이 이루어지고, 기계 학습이라는 단어의 학습이 정확히 무엇을 의미하는지 알 수 있을 것이다.

 

 

1. 신경 세포

 머신러닝 공부를 해보면 신경망(Neural Network)라는 단어를 종종 볼 수 있었을 것이다. 그리고 머신러닝에 사용되는 인공신경망이 사람의 신경을 흉내 내어 만들어졌다는 글도 나오는데, 대체 이게 무슨 소리일까?

ZUM 학습백과. 뉴런의 구조(http://study.zum.com/book/11779)

  • 위 그림은 인간의 신경 세포인 뉴런이다.
  • 뉴런은 가지돌기(수상돌기)에 여러 신호가 도착하면 신경 세포체에서 이를 합치고, 합쳐진 신호가 특정 임계 값을 넘으면, 출력 신호가 생성되어 축삭 돌기를 통해 다음 뉴런으로 신호가 전달된다.
  • 여기서 중요한 포인트는 다음과 같다.
    • A. 여러 신호가 신경 세포체로 전달된다.
    • B. 전달된 신호는 하나로 합쳐진다.
    • C. 합쳐진 신호가 특정 임계값을 넘으면, 전달된다.
  • 나중에 다룰 이야기지만, 위 이야기에서 정보가 하나로 합쳐져서 전달되는 과정이 활성화함수(Activation function)를 나타내는 부분이라고 생각하자(이 건 나중에 다시 이야기하니깐 대충 넘기자)

 

 

 

 

2. 퍼셉트론(Perceptron)

  • 퍼셉트론은 위에서 나온 신경 세포를 알고리즘화한 것으로, 딥러닝의 기본이 되는 개념이다.
  • 퍼셉트론은 N개의 입력 받아 1개의 신호를 출력한다.
  • 퍼셉트론은 받아들여 합친 신호가 임계값보다 크면 1을 출력하고, 임계값보다 작으면 0을 출력하여, 정보를 전달하거나 전달하지 않는다.

입력이 2개인 퍼셉트론

  • 위 퍼셉트론 그림에서 원은 노드(Node) 혹은 뉴런(Neuron)이라고 부르며, 선은 엣지(Edge)라고 부른다.
  • 노드에서 다음 노드로 정보가 전해질 때, 가중치($w_1$, $w_2$)가 곱해져 전달된다.
  • 전달되는 값과 가중치가 곱해진 값($w_1x_1$)의 합($w_1x_1 + w_2x_2$)이 임계값 $\theta$(theta)보다 크면 1이, 작으면 0이 출력되는데, 이는 위에서 언급한 신경세포에서 신호가 전달되는 과정을 그대로 따라한 것과 같다.
  • 이를 수식으로 나타내면 다음과 같다.

$$y = \begin{cases}
 0 \ \ \ (w_1x_1 + w_2x_2 \leq \theta) \\ 
 1 \ \ \ (w_1x_1 + w_2x_2 > \theta)
\end{cases}$$

  • 위 함수를 보면, 위 신경세포에서 설명한 신호가 움직이는 과정을 쉽게 표현한 것임을 알 수 있다.

 

 

 

3. 퍼셉트론의 구현

  • 앞서 입력 노드가 2개인 퍼셉트론의 함수를 적어보았다. 만약, 위 함수를 파이썬 코드로 구현한다면, 그것이 바로 퍼셉트론을 구현하는 것이 아니겠는가. 한 번 만들어보도록 하자.
# Perceptron 함수를 코드로 구현해보자
>>> def Perceptron(x1, x2, w1, w2, theta):

>>>     y = w1*x1 + w2*x2
            
>>>     if y <= theta:
>>>         return 0
                
>>>     elif y > theta:
>>>         return 1
  • $x_1$과 $x_2$는 퍼셉트론의 노드이므로, 0과 1의 값만 나올 수 있다.
  • $x_1=0,\ x_2=1,\ w_1=0.1,\ w_2=0.3,\ theta=0.6$으로 함수를 실행해보자 
>>> Perceptron(x1=0, x2=1, w1=0.1, w2=0.3, theta=0.6)
0
  • 위 결과를 보면, 0*0.1 + 1*0.3 <= 0.6으로 나와 0이 반환된 것을 알 수 있다.
  • 이를 보면, 가중치는 해당 노드에서 전달되는 정보의 중요도를 어느 정도나 강하게 줄 것인지를 따지는 것이고, 임계값은 받아들인 신호를 얼마나 타이트하게 평가할 것인가를 판단하는 수단이라는 것을 알 수 있다.

 

 

 지금까지 신경망의 기본이 되는 신경 세포, 퍼셉트론의 기본 개념에 대해 학습해보았다. 다음 학습에선 퍼셉트론을 이용하여 단순한 논리 회로를 적용하는 방법에 대해 학습해보도록 하겠다.

 

 

 해당 포스팅은 사이토 고키의 "밑바닥부터 시작하는 딥러닝"책을 참고하여 작성하였다. 해당 책은 꽤 얇고 내용도 이해하기 쉽게 써놨으므로, 머신러닝을 시작하는 초보가 읽기에 괜찮은 책이다. 시간 날 때, 한 번 읽어보기 바란다(참고로 PPL이 아니다! 내 돈 주고 내가 산 괜찮은 책 소개다!).

728x90
반응형
728x90
반응형

 현재 컴퓨터를 사용하는 모든 분야에서 가장 핫한 분야를 한 가지 고르라고 한다면, 장담컨대 "인공지능 > 머신러닝 > 딥러닝"을 꼽을 수 있을 것이다. 알파고 이후로 모든 매체에서는 인공지능, 머신러닝, 딥러닝이라는 단어를 외치고 있으며, 이 것이 중요하다는 것은 알겠는데 구체적으로 어떻게 중요한지, 그리고 이 것이 구체적으로 무엇인지를 제대로 설명해주는 곳은 많지가 않다.

 이번 포스트에서는 "인공지능 > 머신러닝 > 딥러닝"으로 이어지는 단어들에 대해 설명하고, 앞으로의 학습 방향에 대해 이야기해보도록 하겠다.

인공지능의 포함 관계

 

 

1. 인공지능(AI)이란?

 인공지능이라는 단어를 들으면 막연하게 "터미네이터 같은 인간과 유사한 생김새를 갖고 있으며, 인간보다 뛰어난 능력을 가진 존재"라는 생각이 들 것이다. 인공지능은 크게 General AI(일반적인 AI)와 Narrow AI(좁은 AI) 두 가지로 나뉘는데, 이를 설명해보면, 대충 감이 올 것이다.

General AI

  • 영화에 나오는 인공지능으로 인간처럼 사고를 하며, 상황에 맞는 다양한 활동을 하는 인공지능을 말한다.
  • 예를 들자면 자신의 다리로 계단이던 길이던 횡단보도던 알아서 돌아다니고, 필요에 따라 판단하여 택시나 버스를 타고, 에너지가 부족하다 싶으면 알아서 에너지도 충전하고, 회사에 출근해서 눈치를 살피는 그런 인간과도 같은 존재를 가리킨다.
  • 이런 복합적인 기능을 자유자재로 동시에 수행하는 것은 아직까진 우리 상상 속에만 존재하며, 영화나 드라마에서만 나오는 존재다.

Narrow AI

  • 말 그대로 좁은 영역에서의 인공지능을 말하며, 특정한 행동에 대해서만 특화 돼 있는 인공지능이다. 
  • 가장 유명한 인공지능인 알파고는 바둑에 특화된 인공지능으로, 학습을 위해 바둑 기보들을 수집하고, 학습된 내용을 바탕으로 스스로 경쟁하여 바둑을 학습해, 바둑이라는 게임에서 승리할 수 있도록 만든 것이다.
  • 학교, 뉴스, 4차 산업 혁명에 해당하는 인공지능이 바로 Narrow AI이다.
  • 우리가 앞으로 학습할 인공지능이 이 곳에 해당한다.

 

 

 

 

2. 머신러닝(Machine Learning)이란?

 머신러닝은 위에서 이야기한 Narrow AI에 속하는데, 말 그대로 기계를 학습시킨다는 말이다.

 갓 태어난 아이는 성장을 하며 말을 배우고, 친구를 사귀는 법을 배우며, 국어, 영어, 수학 같은 학문을 배운다. 나아가 음악을 들었을 때, 이 음악이 어떤 음악이었는지 그 제목을 떠올리기도 하고, 그림을 보고 그림의 제목과 화가의 이름을 맞추기도 한다.

 우리가 처음으로 말을 배웠을 땐, 부모님이 하는 말을 계속 들어왔고, 부모님들은 사물에 사물 이름을 적은 메모장을 붙여놓는 방법 등을 통해 우리를 가르쳤다. 친구를 사귀는 법은 다양한 사람을 만나가며, 어떻게 하면 그들과 유대감을 쌓을 수 있는지 경험으로 익혔다. 국어, 영어, 수학 같은 학문은 계속 책을 보며, 문제를 푸는 방법과 사고하는 방법을 익혔다. 음악이나 그림을 판단하는 방법도 다양한 음악이나 그림을 접하면서 그것들을 구분하는 능력을 쌓았다.

 위 예시에서 우리는 오로지 데이터만을 가지고 지금의 복잡한 작업을 수월하게 할 수 있게 된 것이다. 컴퓨터를 이용한 기계학습 역시 이와 유사하게 이루어진다. 기본적인 머신러닝 알고리즘이 존재하고, 그 알고리즘에 데이터를 부어넣으면, 그 데이터가 가지고 있는 패턴을 찾아내, 그 패턴대로 분류하게 되는 것이 바로 머신러닝이다.

 

 

 

 

3. 딥러닝(Deep Learning)이란?

 1943년 논리학자 윌터 피츠(Walter Pitts)와 신경외과의 워렌 맥컬럭(Warren Mc Cullonch)은 "A Logical Calculus of Ideas Immanent in Nervous Activity"라는 논문에서 딥러닝의 기반이 되는 인공신경망이라는 개념을 등장시켰고, 인간의 신경세포를 모방한 퍼셉트론을 등장시켰다.

 퍼셉트론을 이용한 인공지능 연구능 처음엔 굉장한 인기를 끌었으나, 굵직 굵직한 사건이 터져 몇 번이고 사장될 위기에 처했었다. 처음엔 XOR 게이트로 인해 퍼셉트론은 선형 분류밖에 할 수 없다는 한계점이 등장했고, 이를 다층 퍼셉트론(MLP)라는 개념을 등장시켜 선형 분류의 한계점을 해결하였으나, MLP를 학습시킬 방법이 없다는 한계점이 또 등장하였다. 이는 오류역전파(Backpropagation of errors)라는 기법으로 해결하였으나, 층이 늘어날수록 기울기가 소실되는 문제가 또 등장하고, 은닉층 활성화 함수로 Sigmoid 대신 ReLU를 사용하여 해결하는 등 수많은 과정을 거쳐 지금의 딥러닝이 탄생하게 되었다.

 딥러닝이라는 이름이 생긴 이유도 기존의 다층 퍼셉트론(MLP)에 대한 부정적인 시선을 피하기 위해 딥러닝이라는 새로운 이름을 붙인 것이며, 다층 퍼셉트론(MLP)의 은닉층을 아주 많이 쌓기 때문에 딥(Deep)해진다. 즉, Layer가 깊어진다라는 의미에서 딥러닝이라는 이름이 붙은 것이다.

 딥러닝 역시 머신러닝의 한 갈래에 속하지만, 머신러닝에는 퍼셉트론을 포함하여 수많은 이론들이 존재하므로, 머신러닝과 딥러닝을 분리해서 생각하는 것이 좋다.

 

 

 해당 카테고리에서는 머신러닝에 대해서 학습할 계획이며, 딥러닝에 대해서는 Deep Learning 카테고리에서 따로 학습할 예정이다.

728x90
반응형
728x90
반응형

 지금까지 문자열(string) type을 생성하고 이스케이프 문자, 포맷팅에 대해 학습해보았다. 지금까지 학습한 내용은 문자열을 생성하는 것에 관련 있는 것이지, 문자열을 다루는 내용과는 거리가 멀다고 할 수 있다.

 이번 포스트에서는 문자열을 직접 가지고 노는 문자열 전처리 코드에 대해 학습을 해보겠다.

 

 

문자열 전처리

1. 문자열 연산

 문자열 연산은 우리가 일반적으로 아는 더하기, 빼기, 곱하기와 같은 기능으로, 앞서 학습했던 List에서의 더하기, 곱하기처럼 문자A + 문자B는 문자A문자B가 되며, 문자 A * 3은 문자A문자A문자A가 된다.

# 1. 문자열을 더해보자
>>> A = "Python"
>>> B = "is"
>>> C = "easy"
>>> D = "and"
>>> E = "useful"
>>> F = A + " " + B + " " + C + " " + D + " " + E
>>> print(F)
Python is easy and useful


# 2. 문자열을 곱해보자
>>> A * 2
'PythonPython'


# 3. 문자열을 더하고 곱해보자
>>> G = A + " "
>>> print(G * 3)
Python Python Python 
  • 문자열 더하기는 꽤 유용하게 사용할 수 있는 기능으로, 포맷팅과 동일하게 사용할 수도 있다.
# 문자열 더하기를 포맷팅처럼 사용해보자
>>> AB = A + " " + B + " "
>>> print(AB + C)
>>> print(AB + E)
Python is easy
Python is useful

 

위와 같은 산술 연산 기호를 사용하는 것은 아니지만 문자열 빼기도 가능하다

# 생성된 문자열 F에서 and를 제거해보자
>>> print(F)
Python is easy and useful

>>> F.replace("and ", "")
'Python is easy useful'


# 문자열 F에서 and를 or로 바꿔보자
>>> F.replace("and", "or")
'Python is easy or useful'
  • 문자열 빼기가 문자열 F에서 문자열 D를 제거하는 것이라면, replace 함수를 응용해서 사용할 수 있다.
  • replace(): 문자열.replace(대상 문자, 바꿀 문자) 함수를 사용하면, 대상 문자를 내가 원하는 다른 문자로 바꿀 수 있다.

 

 

 

2. 문자열 인덱싱(슬라이싱)

 문자열 인덱싱은 문자에서 내가 원하는 구간의 문자만 선택하는 방법이다.

# 위에서 생성했던 문자열 F를 가지고 indexing을 해보자
>>> print(F)
'Python is easy and useful'


# 1. 먼저 문자 전체의 길이를 확인해보자
>>> len(F)
25


# 2. 문자열 F에서 첫 문자부터 5번째 문자까지 가지고 와보자
>>> F[0:5]
'Pytho'

# 2.1. 문자열 F를 뒤에서 6번째부터 뒤 모든 문자를 가지고 와보자
>>> F[-6:len(F)]
'useful'

>>> F[-6:]
'useful'
  • len(x): len 함수는 들어간 문자의 길이를 반환한다. x에 list나 DataFrame 등이 들어가는 경우, list는 원소의 수, DataFrame은 Row의 수를 반환한다.
  • 인덱싱에서 [n1:n2] n1에 아무것도 넣지 않는 경우 처음부터인 0을 의미한다. n2에 아무것도 넣지 않는 경우 마지막 위치를 의미한다.
  • 인덱싱한 값을 다른 변수에 담으면, 슬라이싱(부분만 가져오기)이 된다.
# 슬라이싱 기능을 활용하면 원하는 위치만 제거 혹은 다른 문자 끼워넣기가 가능하다.
>>> print(F)
'Python is easy and useful'

# 1. "easy and "를 제거해보자
>>> F[:10] + F[-6:]
'Python is useful'

# 2. useful을 useless로 바꿔보자
>>> F[:10] + F[-6:-3] + "less"
'Python is useless'

 

 위 인덱싱에선 내가 찾고자 하는 문자의 위치를 직접 확인해야 했으나, 문자 위치를 반환하는 함수인 find(), index() 함수를 사용하면, 위치를 수월하게 찾을 수 있다.

# 문자열 F에서 and의 위치를 찾아보자
>>> print(F)
'Python is easy and useful'

>>> F.find("and")   
15
>>> F[15:]
'and useful'    # 단어의 시작 위치가 출력된다.

# index() 함수는 find() 함수와 동일한 기능을 한다.
>>> target_start = F.index("and")
>>> print(target_start)
15

# len() 함수를 섞어서 사용하면 이 문제를 해결할 수 있다.
>>> F[target_start:target_start+len("and")]     # 문자 끝 위치 = 문자 시작 위치 + 문자 길이
'and'
  • 문자열.find(탐색 문자), 문자열.index(탐색 문자) 함수를 사용하면, 해당 문자가 처음 등장한 문자의 위치를 알 수 있다.
  • len() 함수와 섞어서 사용한다면 문자의 끝 위치도 알 수 있다.
  • 그러나 만약, 해당하는 문자가 여러개라면 가장 왼쪽에서 등장한 문자의 위치만 반환한다는 단점이 있다(이는 추후 학습할 정규표현식 함수를 사용하면 수월하게 해결할 수 있다).
  • index() 함수와 find() 함수의 차이는 대상 단어가 없을 때로, find() 함수 사용 시 대상 단어가 없으면 -1이 반환되고, index() 함수는 에러가 발생한다.

 

 

 

3. list와 str

 str type과 list type을 오가게 하는 함수가 있으며, 이를 단순히 말하면 아래와 같다.

  • "구분자".join(대상 문자열): 합치기
  • "대상 문자열".split("구분자"): 쪼개기
>>> target = "Python is fun and useful"

# 1. 문자열을 list로 쪼개보자
>>> target_list = target.split(" ")
>>> print(target_list)
['Python', 'is', 'fun', 'and', 'useful']

# 2. list를 문자열로 합쳐보자
# _(Under bar)로 합쳐보자
>>> target_str = "_".join(target_list)
>>> print(target_str)
Python_is_fun_and_useful

# 3. 생성된 단어를 한 글자 단위로 잘라보자
# join() 함수를 문자열을 대상으로 사용하면, 문자열에서 단어 하나하나 사이에 특정 단어가 들어간다.
>>> put_separator = "|".join(target_str)
>>> print(put_separator.split("|"))
['P', 'y', 't', 'h', 'o', 'n', '_', 'i', 's', '_', 'f', 'u', 'n', '_', 'a', 'n', 'd', '_', 'u', 's', 'e', 'f', 'u', 'l']
  • join() 함수를 문자열을 대상으로 사용 시, 문자열의 단어 하나하나 사이에 join 단어가 들어간다.
  • |는 거의 사용하지 않는 특수 문자 중 하나로 일반적으로 Rawdata에 존재하지 않는다.
  • join() 함수와 split() 함수를 섞어서 사용하면 한 단어 단위로 자를 수 있다.

 

 

 

4. 공백 제거하기

# Target
>>> target = " Python is easy and useful "

# 1. 앞의 공백을 제거하자
>>> target.lstrip()
'Python is easy and useful '

# 2. 뒤의 공백을 제거하자
>>> target.rstrip()
' Python is easy and useful'

# 3. 양쪽 공백을 제거하자
>>> target.strip()
'Python is easy and useful'

# 4. 모든 공백을 제거하자
>>> target.replace(" ", "")
'Pythoniseasyanduseful'
  • 문자열.lstrip(): 왼쪽 공백 제거
  • 문자열.rstrip(): 오른쪽 공백 제거
  • 문자열.strip(): 양쪽 공백 제거
  • 문자열.replace(" ", ""): 모든 공백 제거

 

 

 

5. 대소문자 바꾸기

# Target
>>> target = "Python is easy and useful"

# 1. 소문자를 대문자로 바꿔보자
>>> upper_T = target.upper()
>>> print(upper_T)
PYTHON IS EASY AND USEFUL

# 2. 대문자를 소문자로 바꿔보자
>>> upper_T.lower()
'Python is easy and useful'
  • 문자열.upper(): 소문자를 대문자로 만든다
  • 문자열.lower(): 대문자를 소문자로 만든다

 

 

 

6. 문자열 개수 세기

# target
>>> target = "Python is fun and useful"

# 1. 문자열 전체 길이를 확인해보자
>>> len(target)
25

# 2. 문자열 안에 특정 문자가 몇 개 있는지 확인해보자
>>> target.count(" ")
4

>>> target.count("Python")
1

 

 

 

 지금까지 문자열을 다루는 기본적인 함수에 대해 알아보았다. 위 함수들을 보면, 내가 원하는 단어를 탐색하고 조작하는 부분이 실전에서 필요한 것에 비해 부족하다는 것이 느껴지는데, 이를 보다 체계적으로 할 수 있는 방법이 바로 정규표현식이다.

 다음 포스트에서는 파이썬 정규표현식에 대해 학습해보도록 하겠다.

728x90
반응형
728x90
반응형

  예를 들어 당신이 어떠한 반복되는 문자열을 만드려고, 하고 그 중 일부분만 바꿔야 한다면 어떻게 하겠는가?

# 예를 들어 뽀로로, 크롱의 인사와 짱구, 짱아의 인사 문자열을 생성하려면 어떻게 해야할까?
>>> str0 = "뽀로로: \"크롱 반가워!\"\n크롱:\"오! 뽀로로 좋은 아침이야!\""
>>> str1 = "짱구: \"짱아 반가워!\"\n짱아:\"오! 짱구 좋은 아침이야!\""
>>> print(str0)
>>> print("\n")
>>> print(str1)
뽀로로: "크롱 반가워!"
크롱:"오! 뽀로로 좋은 아침이야!"

짱구: "짱아 반가워!"
짱아:"오! 짱구 좋은 아침이야!"

 위 예시처럼 일일이 그 문자열을 만들어 새로 지정해 줄 것인가? 이는 매우 비 경제적인 방법인데, 이번 포스트에선 문자열의 일부를 손쉽게 바꿀 수 있는 방법인 문자열 포맷팅에 대해 학습해보겠다.

 

 

문자열 포맷팅(String Formatting)

 지난 포스트인 이스케이프 문자 예제에서 뽀로로, 크롱과 같은 문자열 내 특정 문자가 반복되어 출력되는데, 이 부분만 자동으로 바꿀 수 있다면, 보다 적은 코드만 써도 되지 않을까? 라는 생각이 들지 않는가?

 문자열 포맷팅은 코드를 더 경제적으로 쓸 수 있는 방법 중 하나로, 출력되는 문자열에서 일부분만 쉽게 바꿀 수 있는 방법 중 하나다.

 문자열 포맷팅은 크게 3가지 방법이 있다.

  1. % formating
  2. {} formating
  3. f-string

 

 

1. % formating

# 1. % formating
>>> print("%s: %s, 반가워!" %("뽀로로", "크롱"))
>>> print("%s: %s, 좋은 아침이야!" %("크롱", "뽀로로"))
뽀로로: 크롱, 반가워!
크롱: 뽀로로, 좋은 아침이야!
  • 위 예시를 보면, %s라는 문자와 %()라는 처음 보는 문자가 들어간 것을 볼 수 있다.
  • %s %d % ("str", 2) 이 기본적인 방식이다. 여기서 %s, %d와 같은 문자를 문자열 포맷 코드라고 한다.
  • 문자열 포맷 코드는 다음과 같다.
코드 설명 코드 설명
%s 문자열(string) %d 정수(integer)
%c 문자 1개(character) %f 부동소수(floating-point)
  • 참고로 %s의 경우 문자형이나, 숫자, 소수 모두 문자형으로 변형이 가능하므로, %s를 넣는 경우, 모든 형태의 값을 넣을 수 있다.
  • 이 밖에도 8진수(%o), 16진수(%x)가 더 있긴 하지만, %s, %d, %f만 사용할 수 있어도 충분하다.
  • 참고로 %를 문자로 그냥 출력하고 싶다면 %%를 입력해야한다.
# 위 코드를 좀 더 쉽게 써보자
>>> name1 = "뽀로로"
>>> name2 = "크롱"
>>> print("%s: %s, 반가워! \n%s: %s, 좋은 아침이야!" %(name1, name2, name2, name1))
뽀로로: 크롱, 반가워! 
크롱: 뽀로로, 좋은 아침이야!

>>> name3 = "짱구"
>>> name4 = "짱아"
>>> print("%s: %s, 반가워! \n%s: %s, 좋은 아침이야!" %(name3, name4, name4, name3))
짱구: 짱아, 반가워! 
짱아: 짱구, 좋은 아침이야!
  • 위 코드 같이 반복 출력하고자 하는 Data("뽀로로", "크롱")를 변수(name1, name2)에 담아서 사용하면 보다 쉽게 쓸 수 있다.
  • 그러나 위 방법의 경우, 문자를 넣어주고 싶은 위치랑 %()안의 변수 위치가 동일해야하므로, Data가 문자열에서 들어갈 위치를 헷깔릴 수 있다는 단점이 있다.

 

 

 

2. {} formating

# {} formating을 써보자
print("{name1}: {name2}, 반가워!\n{name2}: 오! {name1} 좋은 아침이야!".format(name1="뽀로로", name2="크롱"))
뽀로로: 크롱, 반가워!
크롱: 오! 뽀로로 좋은 아침이야!
  • {} format은 문자열 내에 원하는 변수를 지정하여 사용할 수 있다.
  • % formating과 달리 변수의 위치를 구체적으로 알 수 있다.
  • 이를 def 코드를 사용해서 함수로 만든다면, 보다 효율적으로 사용할 수 있다.
# def 코드를 사용해서 만들어보자
>>> def hello(name1, name2):
>>>     print("{name1}: {name2}, 반가워!\n{name2}: 오! {name1} 좋은 아침이야!".format(name1=name1, name2=name2))
    
>>> hello("짱구", "짱아")

짱구: 짱아, 반가워!
짱아: 오! 짱구 좋은 아침이야!
  • 그러나, 이 방법은 .format(변수이름=변수)를 넣어줘야하기 때문에 코드가 길어진다는 단점이 있다.

 

 

 

3. f-string

% formating과 {} formating을 비교해보면, 각각 코드를 만드는 데에 있어 장점과 단점이 나뉘는 것을 알 수 있다.

  • % formating은 문자열 포맷팅 밖에서 지정한 변수를 가져갈 수 있다.
  • {}.formating은 문자열 내 포맷팅 된 변수들의 위치를 알 수 있다.
  • 위 장점을 적절히 섞는다면 보다 코드를 수월하게 짤 수 있지 않을까? > f-string을 통해 이를 해결할 수 있다.
# f-string 포맷팅을 사용해보자
>>> name1 = "뽀로로"
>>> name2 = "크롱"
>>> print(f"{name1}: {name2}, 반가워!\n{name2}: 오! {name1} 좋은 아침이야!")
뽀로로: 크롱, 반가워!
크롱: 오! 뽀로로 좋은 아침이야!
  • f-string은 위 % formating이나 {} formating보다 코드가 단순하다.
  • 문자열 밖에서 문자열에 들어갈 가변적인 변수를 지정하고, 문자열 앞에 f를 붙이면 된다.
  • 문자열 내에선 {} formating과 같은 방식으로 문자열을 적으면 된다.
  • 위 코드를 def 코드를 이용해서 함수로 만들어보자.
# 함수화 해보자
>>> def hello(name1, name2):
>>>     print(f"{name1}: {name2}, 반가워!\n{name2}: 오! {name1} 좋은 아침이야!")
    
>>> hello("짱구", "짱아")


짱구: 짱아, 반가워!
짱아: 오! 짱구 좋은 아침이야!
  • 위의 {} formating을 사용해서 만든 함수보다 코드가 단순하다는 것을 알 수 있다.

 

 

 

 지금까지 문자열의 일부만 바꾸는 방법인 문자열 포맷팅에 대해 알아보았다. 이 중 f-string이 가장 코드가 단순하고, 직관적이므로, 가능하면 f-string을 쓰길 바란다.

 다음 포스트에서는 문자열을 가지고 노는 방법인 문자열 전처리에 대해 학습해보겠다.

728x90
반응형
728x90
반응형

 지난 포스트에서는 Python의 기본적인 자료형에 대해 공부해보았다. "Python-기초: 1.0. 자료형(1) - scalar"에서 Data type으로 int, float, None, Boolean은 나왔으나, 정작 문자열은 나오지 않았다.

 이번 포스트에서는 data type 중 문자열 Type인 string에 대해 심도 깊게 다뤄보도록 하겠다. 

 

 

문자열(String)

  • Python에서 문자열은 ''(Quotation)나 ""(Double Quotation) 안에 문자를 넣어서 만든다.
  • Python의 기본 인코딩은 utf-8이므로, R과 달리 한글에 대한 텍스트 마이닝이 깔끔하게 잘 수행된다.
  • 문자열 데이터를 처리하여, 그 안에 숨어 있는 정보를 찾아내는 전반적인 과정을 텍스트 마이닝(Text Mining)이라 한다.

※ 텍스트마이닝(Text Mining)

  • 현장에서 접하는 대다수의 데이터는 숫자로 이루어진 연속형 데이터보다 Log Data 같은 문자, 사진 같은 이미지, 동영상, 음악과 같은 비정형 데이터가 대부분이다.
  • 대부분의 전처리(Data Handling)는 이러한 비정형 데이터를 분석에 용이한 숫자 데이터로 변환해주는 과정이다.
  • 문자형 Data를 연속형 데이터로 변환하는 경우, 크게 2가지 방법이 있다.
    1. 범주화: 문자에 해당하는 숫자를 배정 - 리소스를 덜 먹음
    2. 벡터화: One-Hot Vector, Word2Vec 등의 방법 사용 - 일반적으로 기계학습에서 사용

 

 

 

문자열 Data를 만들어보자

# 문자열 Data를 만들어보자.
# 1. "" or ''를 사용해서 만든다.
>>> str1 = "Python is very useful"
>>> print(str1)
Python is very useful

>>> str2 = 'Python is a lot of fun'
>>> print(str2)
Python is a lot of fun

>>> str3 = """Python is easy and fun"""
>>> print(str3)
Python is easy and fun

>>> str4 = '''So let's do Python'''
>>> print(str4)
So let's do Python
  • 문자열 Data는 ""나 ''를 사용해서 만들며, "나 ' 기호를 3번 연속 사용해서 만들 수도 있다.
  • 보통 """나 '''로 만드는 경우는 긴 문장이나 주석을 넣을 때 사용한다.
# 문자열 안에 문자열 생성 기호인 ''나 ""를 넣고 싶은 경우엔 어떻게 할까?
>>> print("Let's do our best today")
Let's do our best today

>>> print('Pororo said "Hello" to Crong')
Pororo said "Hello" to Crong

>>> Frozen = """
    Anna:
    "Elsa?  Do you want to build a snowman?
    "Come on let's go and play.
    I never see you anymore. Come out the door.
    It's like you've gone away.
    We used to be best buddies
    And now we're not. I wish you would tell me why.
    Do you want to build a snowman?
    It doesn't have to be a snowman."

    Elsa:
    "Go away, Anna."

    Anna:
    "...Okay bye."
    """
    
>>> print(Frozen)

Anna:
"Elsa?  Do you want to build a snowman?
"Come on let's go and play.
I never see you anymore. Come out the door.
It's like you've gone away.
We used to be best buddies
And now we're not. I wish you would tell me why.
Do you want to build a snowman?
It doesn't have to be a snowman."

Elsa:
"Go away, Anna."

Anna:
"...Okay bye."
  • 짧은 문장 안에 '나 "가 들어가야한다면 그에 상응하는 문자로 묶어주면 된다.
  • 그러나 이 두 가지가 모두 들어가야한다면, """ 문장 """으로 묶어주면 된다.
  • 또는 escape 문자인 \을 사용하면 된다.

 

 

 

이스케이프 문자(Escape Sequence)

파이썬을 포함한 각종 언어에서는 잘 사용하지 않는 특수 문자나 특수문자 + 문자 조합에 특정 기능을 넣어 놓는다. 그러나, 가끔 이 이스케이프 문자가 실제 문자 Data 대상인 경우도 있기 때문에 이스케이프 문자가 아님을 알려주는 방법을 숙지할 필요가 있다.

이스케이프 문자 이름 설명
\b 벡스페이스 뒤로 한 칸 삭제
\t 문자열 사이에 탭 간격 생성
\n 라인피드 줄 바꿈
\f 폼피드 현재 커서를 다음 줄로 이동
\r 캐리지 현재 커서를 가장 앞으로 이동
\\ 역슬래시 \를 이스케이프 문자 앞에 사용하는 경우 그대로 출력
  • 위 표에서 많이 사용되는 것은 탭, 라인피드, 이스케이프 문자 앞에 \ 사용하기이므로, 나머지 이스케이프 문자에 대해선 크게 신경 쓰지 말자.
  • 키보드에서 \는 존재하지 않는데, ₩ 키가 동일한 기능을 한다.
# 이스케이프 문자를 사용해보자
>>> str5 = "뽀로로: \"크롱 반가워!\"\n크롱:\"오! 뽀로로 좋은 아침이야!\""
>>> print(str5)
뽀로로: "크롱 반가워!"
크롱:"오! 뽀로로 좋은 아침이야!"

# 이스케이프 문자를 그대로 출력시켜보자
>>> str5 = "뽀로로: \"크롱 반가워!\"\\n크롱:\"오! 뽀로로 좋은 아침이야!\""
뽀로로: "크롱 반가워!"\n크롱:"오! 뽀로로 좋은 아침이야!"

 

  • 위 예제에서 역 슬래시 사용 후 "나 ' 같은 특정 기능이 들어간 특수 문자를 넣으면 그대로 출력되는 것을 알 수 있다.
  • 이스케이프 문자에서 \n나 \t는 Data를 line 단위로 가져오기, tap 단위로 구분 지어 가져오기(구분자)를 하는 경우에 문자 안에 해당 문자가 들어 있어, Row를 잘못 인식할 수도 있다(실제 Row의 수보다 더 많은 Row를 생성).
  • 텍스트 데이터를 다룰 때, 이스케이프 문자나 ' or "로 인해 의도치 않은 결과가 출력 될 수 있다.

 

 

 

 이번 포스트에서는 가볍게 문자열을 만드는 방법과 이스케이프 문자에 대해 알아보았다. 이스케이프 문자는 반드시 숙지하길 바라며, 최소한 \n이 내려쓰기, \t는 탭이라는 것은 꼭! 외워놓기 바란다.

 Data를 가지고 오는 방법 중 txt data를 line별로 가지고 오거나, 탭을 구분자로 가져오는 경우가 많은데, 대상 Data 안에 해당 이스케이프 문자가 들어 있다면(예를 들어 URL Log Data), 데이터를 잘못 불러오는 문제가 발생할 수 있다.

 다음 포스트에선 자동으로 문자열의 일부를 바꾸는 방법인 포맷팅(Formating)에 대해 학습해보겠다. 

 

728x90
반응형
728x90
반응형

 자, 드디어 마지막 기초 자료형인 DataFrame이다. DataFrame은 pandas의 대표적인 Type이며, R을 공부해 본 사람이라면, 상당히 친숙하게 느껴지는 단어일 것이다.

 pandas의 DataFrame은 R의 Dataframe을 Python에서도 사용해보기 위해 만들어졌으며, R에서 할 수 있는 대부분의 기능을 판다스에서도 구현할 수 있다.

 이번 포스트에서는 데이터 분석가들의 필수 Type인 DataFrame이 어떻게 생겼는지와 아주 대략적인 대표 기능만 살펴보고 바로 넘어가도록 하자.

 

 

 먼저 DataFrame을 만들어보자.

  • DataFrame을 만드는 방법은 크게 2가지가 있다.
    1.  길이가 동일한 list들을 컬럼 하나하나에 배정하는 방법
    2. M*N 행렬 형태의 Data(Array, Tupple)를 DataFrame에 넣는 방법
# pandas 모듈을 가지고 오자
>>> import pandas as pd
>>> import numpy as np


# 1. 길이가 동일한 list들을 DataFrame에 넣어보자
# DataFrame에 들어갈 길이가 같은 list들을 만들자
>>> name = ["민철", "기훈", "재성", "현택", "윤기"]
>>> math = [40, 60, 80, 75, 65]
>>> english = [75, 80, 65, 80, 70]
>>> science = [85, 70, 75, 80, 60]

# list들을 이용해서 DataFrame을 만드는 경우는 다음과 같다
>>> DF = pd.DataFrame({"name":name, "math":math, "english":english, "science":science})
>>> DF

name	math	english	science
0	민철	40	75	85
1	기훈	60	80	70
2	재성	80	65	75
3	현택	75	80	80
4	윤기	65	70	60



# 2. array를 이용해서 DataFrame을 만들어보자.
# 10, 100 사이의 임의의 값으로 만들어진 행렬을 생성하자
>>> row_number = 50
>>> score_mat = np.random.randint(10, 100, size=(row_number, 4))

# ID를 만들어보자
>>> ID_list = []
>>> for i in range(row_number):
    
	    ID = "A" + str(i)
    	ID_list.append(ID)
    
# shape을 맞춰서 ID_array와 score_mat을 병합시켜보자
>>> ID_array = np.array(ID_list)
>>> ID_array = ID_array.reshape((50, 1))

>>> data_array = np.hstack((ID_array, score_mat))

# array를 DataFrame을 만들어보자
>>> DF2 = pd.DataFrame(data_array, columns=["ID", "math", "English", "science", "Korean"])
# 생성한 DataFrame의 상위 10개만 출력해보자
>>> DF2.head(10)


ID	math	English	science	Korean
0	A0	35	38	62	51
1	A1	52	29	40	93
2	A2	28	16	99	71
3	A3	93	42	61	48
4	A4	23	60	39	48
5	A5	93	96	16	55
6	A6	13	69	88	90
7	A7	31	18	80	30
8	A8	59	12	66	93
9	A9	54	70	57	38
  • DataFrame을 처음 보면 마치 엑셀에서 우리가 일반적으로 만들던 표랑 굉장히 유사하다는 것을 알 수 있다.
  • DataFrame에는 각 열(Column)별로 동일한 데이터 타입을 넣을 수 있다.
  • pd.DataFrame() 함수를 통해 DataFrame을 만들 수 있다.
  • np.random.randint(시작 값, 끝 값, 형태) 함수는 시작 값, 끝 값 사이에서 랜덤한 값이 담긴 array를 생성한다.
  • np.hstack((array1, array2)) 함수는 두 array를 열을 기준으로 병합한다.
  • DataFrame.head(숫자) 함수는 내가 숫자만큼 DataFrame을 출력한다.

 

 

DataFrame의 컬럼별 dtype을 확인해보자

# DataFrame의 data type을 확인해보자
>>> DF2.dtypes
ID         object
math       object
English    object
science    object
Korean     object
dtype: object


# math, English, science, Korean 컬럼을 정수 type으로 바꿔보자
>>> DF2["math"] = DF2["math"].astype("int64")
>>> DF2["English"] = DF2["English"].astype("int64")
>>> DF2["science"] = DF2["science"].astype("int64")
>>> DF2["Korean"] = DF2["Korean"].astype("int64")
>>> DF2.dtypes
ID         object
math        int64
English     int64
science     int64
Korean      int64
dtype: object
  • DataFrame.dtypes 함수를 통해 DataFrame의 각 컬럼들의 Type을 확인할 수 있다.
  • DataFrame["컬럼"].astype("바꿀 dtype") 함수를 통해 DataFrame의 해당 컬럼 dtype을 바꿀 수 있다.

 

 

DataFrame을 Slicing 해보자.

# 10번 row부터 20번 row까지 출력해보자
>>> DF2[10:20]
	ID	math	English	science	Korean
10	A10	78	24	99	79
11	A11	41	87	83	10
12	A12	61	71	31	78
13	A13	74	80	32	99
14	A14	20	19	95	38
15	A15	24	67	22	24
16	A16	39	53	41	82
17	A17	34	57	52	67
18	A18	34	60	27	73
19	A19	27	35	91	81




# 수학 80점 이상인 Row만 출력해보자
>>> DF2[DF2["math"] >= 80]
	ID	math	English	science	Korean
2	A2	90	70	70	72
4	A4	90	27	64	42
8	A8	99	21	71	92
9	A9	89	61	11	30
28	A28	81	29	27	86
32	A32	84	19	89	31
44	A44	97	73	36	78
45	A45	80	95	54	12
48	A48	86	19	99	83
  • pandas의 dataFrame은 Numpy의 array와 동일한 방법으로 Slicing 할 수 있으며, 내가 원하는 조건에 대한 Row도 쉽게 가져올 수 있다.

 

 

 이번 포스트에서는 DataFrame에 대해 아주 간략하게 훑어만 봤는데, 설명을 보다 보면 설명이 지나치게 부족하지 않는가? 하는 생각이 들 것이다. 

 pandas의 DataFrame 역시 Numpy의 array와 마찬가지로 그 영역이 매우 크기 때문에 따로 카테고리를 만들어서 세세하게 설명하고자 한다.

 이번 포스트에서는 맛보기로 DataFrame이 어떻게 생겼는지만 인식하는 수준에서 끝내고, 추후 Python-pandas 카테고리의 포스트에서 pandas의 각 기능들을 세세하게 따져보도록 하겠다.

 
728x90
반응형
728x90
반응형

 이번 포스트에서는 Dictionary에 대해 살펴보도록 하겠다.

 

 

Dictionary

개요

  • Dictionary는 말 그대로 사전이라고 할 수 있으며, 사전은 기본적으로 "단어: 설명"의 구성으로 돼있다.
  • Python의 Dictionary 역시 key : value 관계로 이루어져 있으며, key를 이용해 해당하는 value를 받을 수 있다.
  • Dictionary의 안에는 scalar, list, array, DataFrame 등 다양한 Type의 Data 담을 수 있다.
  • Dictionary의 key는 순서가 따로 없으며, 내가 원하는 key에 해당하는 value를 얻고자 할 때, 순서가 없으므로 순차적으로 탐색하지 않고, 바로 value를 가지고 오므로 속도가 매우 빠르다
  • Dictionary의 안에 또 Dictionary를 넣을 수 있으며, 이 구조는 마치 Tree 구조와 같다.

 

 

 위 이야기만 보면 잘 와닿지 않으므로, 실제로 Dictionary를 만들어보자.

# Dictionary를 만들어보자.
>>> dict_a = {}
>>> type(dict_a)
dict

>>> dict_b = dict()
>>> type(dict_b)
dict
  • Dictionary는 위와 같이 dict()라는 함수를 쓰거나 {}를 이용해서 만들 수 있다.

 

 

 이번엔 Dictionary에 Data를 넣어보자

# Data를 넣어보자
>>> dict_c = {"아침":"만두", "점심":"햄버거", "저녁":"된장찌개"}
>>> dict_c
{'아침': '만두', '점심': '햄버거', '저녁': '된장찌개'}
  • Dictionary에는 key:value로 Data를 넣는다.
  • key에는 문자형("", ''로 묶인!), scalar(정수, 소수, None, Boolean)가 들어갈 수 있다.
  • value엔 무엇이든지 다 들어갈 수 있다.

 

 

 조금 더 복잡하게 Data를 넣어보자

>>> dict_c = {"아침":{14:"만두", 15:"피자", 16:"곰탕"},
              "점심":{14:"햄버거", 15:"떡볶이", 16:"라면"},
          	  "저녁":{14:"된장찌개", 15:"김치찌개", 16:"삼겹살"}}
>>> dict_c
{'아침': {14: '만두', 15: '피자', 16: '곰탕'},
 '점심': {14: '햄버거', 15: '떡볶이', 16: '라면'},
 '저녁': {14: '된장찌개', 15: '김치찌개', 16: '삼겹살'}}
  • dictionary 안에는 dictionary를 포함한 다양한 type의 data를 넣을 수 있다.

 

 

 야식이라는 key를 추가해보자

# "야식"이라는 새로운 Dictionary를 추가해보자
>>> dict_c["야식"] = {14:"김밥"}
>>> dict_c
{'아침': {14: '만두', 15: '피자', 16: '곰탕'},
 '점심': {14: '햄버거', 15: '떡볶이', 16: '라면'},
 '저녁': {14: '된장찌개', 15: '김치찌개', 16: '삼겹살'},
 '야식': {14: '김밥'}}
  • dict["key] = value를 사용하면 새로운 key와 value를 추가할 수 있다.

 

 

 이번에는 dict_c의 key가 무엇이 있는지 가져와보자

# Dictionary의 key들을 가지고 와보자
>>> dict_c.keys()
dict_keys(['아침', '점심', '저녁', '야식'])


# Dictionary 안의 "아침"dictionary의 key들을 가지고 와보자
>>> dict_c["아침"].keys()
dict_keys([14, 15, 16])


# key "아침"의 16일 식단이 무엇인지 알아보자
>>> dict_c["아침"][16]
'곰탕'


# key "야식"에 16일 식단을 추가해보자
>>> dict_c["야식"][16] = "짜파게티"
>>> dict_c
{'아침': {14: '만두', 15: '피자', 16: '곰탕'},
 '점심': {14: '햄버거', 15: '떡볶이', 16: '라면'},
 '저녁': {14: '된장찌개', 15: '김치찌개', 16: '삼겹살'},
 '야식': {14: '김밥', 16: '짜파게티'}}
 
 
# 알고보니 15일 저녁에 라볶이를 먹었다. 수정해보자
>>> dict_c["저녁"][15] = "라볶이"
>>> dict_c
{'아침': {14: '만두', 15: '피자', 16: '곰탕'},
 '점심': {14: '햄버거', 15: '떡볶이', 16: '라면'},
 '저녁': {14: '된장찌개', 15: '라볶이', 16: '삼겹살'},
 '야식': {14: '김밥', 16: '짜파게티'}}
  • Dictionary의 key나 value는 쉽게 추가, 수정할 수 있으며, 내가 원하는 것을 가져올 수 있다.

 

 

때로는 Dictionary를 이용해서 다양한 Data들을 담아놓는 거대한 선반 역할을 할 수도 있다.

# 기존에 배웠던 Type들을 모두 넣어보자
>>> import tensorflow as tf
>>> import numpy as np

>>> dict_d = {"scalar_1":int(32.9),
    	      "list_1":["A1", "A2", "A3", "A4"],
        	  "array_1":np.array([[1,3,5,7],[2,4,6,8]]),
          	  "tensor_1":tf.zeros(shape=(2, 3))}

>>> dict_d
{'scalar_1': 32,
 'list_1': ['A1', 'A2', 'A3', 'A4'],
 'array_1': array([[1, 3, 5, 7],
        [2, 4, 6, 8]]),
 'tensor_1': <tf.Tensor: shape=(2, 3), dtype=float32, numpy=
 array([[0., 0., 0.],
        [0., 0., 0.]], dtype=float32)>}
        
        
>>> dict_d["tensor_1"]
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[0., 0., 0.],
       [0., 0., 0.]], dtype=float32)>
  • Dictionary에는 다양한 종류의 Data를 넣어놓고 내가 필요한 Data를 꺼내 쓰는 곧간처럼 쓸 수 있다.
  • 말 그대로 Dictionary는 사전이므로, Tokenize 된 단어와 벡터들을 연결해서 word:Vector 사전으로 쓸 수도 있다.
  • Dictionary의 형태는 또 다른 자주 쓰이는 Type인 json과 동일하다. 그러므로, json을 사용하고자 하는 경우 Dictionary를 잘 다룰 수 있으면 매우 편하다.

 

 

Json

  • json은 데이터 분석을 위해서 다룰 줄 알아야 하는 Type 중 하나이지만, dictionary와 거의 유사하므로 따로 설명하지는 않곗다.
  • json은 Dictionary처럼 Data가 key:value로 이어진 형태이며, 따옴표(')와 큰따옴표(")로 발생하는 문제만 잘 해결한다면 Dictionary를 그대로 json으로 변환해서 사용해도 된다.
  • json은 json 모듈을 이용해 Python의 객체(Dictionary)를 Json 문자열로 변환시키면 된다.
  • 판다스의 DataFrame은 key(column: 열)과 value(row: 행)으로 서로 연결된 형태이므로, 사실 Dictionary와 굉장히 유사한 형태이다. 그러므로 Pandas의 DataFrame도 json 형태로 쉽게 만들 수 있다.
  • 추후 json module에 대해 설명하며 json에 대해 더 자세히 다루도록 하겠다.

 

 

 

 이번 포스트에서는 Dictionary에 대해 알아보았는데, 이번 포스트는 지금까지 포스트 중 가장 성의가 없지 않나?라는 생각이 들 정도로 글의 양이 적은 거 같다.

 다만, 위 함수들만 있어도 Dictionary를 사용하는데 큰 지장은 없으므로, 굳이 사족을 달지는 않겠다.

 다음 포스트에서는 데이터 분석가에게 익숙한 데이터 타입 중 하나인 DataFrame을 간략히 설명하고 기초 자료형에 대한 설명을 마치도록 하겠다.

728x90
반응형
728x90
반응형

 이전 포스트에서 Numpy의 array에 대해 간략하게 훑어보았다. 이번 포스트에선 머신러닝에서 대표적으로 사용되는 모듈인 tensorflow의 고유 Type 중 하나인 Tensor에 대해 학습해보겠다.

 

 

tensor

개요

  • Tensorflow는 Google에서 개발한 머신러닝의 대표적인 모듈로 tensor는 이 tensorflow의 대표적인 Type이지만, 정작 Tensorflow를 이용해서 머신러닝을 할 때에는 사용할 일이 많지 않은 type이기도 하다.
  • "Tensorflow를 활용해서 기계학습을 진행하는데 tensor를 쓰지 않는다니??"라는 생각이 들 수 있는데, tensorflow로 기계학습 진행 시, 일반적으로 keras를 이용해서 model을 생성하게 되고, 그 모델에 들어갈 데이터셋의 핸들링 과정에서 tensor로 핸들링하는 것보다 Numpy의 array를 이용해서 핸들링할 일이 더 많기 때문이다.
  • 애초에 Tensorflow의 tensor와 Numpy의 array의 관련 함수의 상당수가 거의 유사하다 보니, 여기저기 많이 쓰여 익숙하게 쓰는 Numpy의 array가 더 편하기 때문이기도 하다.

 

 

Tensor란?

  • Tensor란 N 차원의 배열(array)을 의미한다.
  • 일반적으로 1차원 배열을 벡터(Vector), 2차원 배열을 행렬(Matrix), 3차원 이상의 배열을 다차원 배열이라고 하며, 이들 모두를 통틀어서 Tensor라고 한다.
  • Tensor는 N 차원 배열이므로, 배열을 다루는 Numpy의 array와 태생적으로 기능이 유사할 수 밖에 없다.

 

 

Rank

Rank 이름 내용
0 스칼라 원소 1개, Python-기초: 1.0. 자료형(1) - scalar 참조
1 벡터 1차원 array, Vt = [0.1, 0.2, 0.3]
2 행렬 2차원 array, Mt = [[1, 3, 5] , [2, 4, 6]]
3 3 차원 텐서 3차원 array - Channel 추가
n n 차원 텐서 n차원 array - 축이 n개인 array
  • 뭔가 대충 설명한 느낌이 강한데, 보다 구체적으로 이해하려면 머릿속에 그림을 그려봐야한다.
  • Scalar > Vector > Matrix > 3-Tensor 이런 식으로 하나하나 층을 쌓아보자

  • Scalar를 하나의 원소로 보고, 그 원소가 일렬로 쭉 쌓으면 Vector, 그 Vector를 아래로 쭉 쌓으면 Matrix, Matrix를 N개의 층을 쌓으면 N-Tensor가 되는 것이다.
  • 보통 3-Tensor는 그림을 Tensor화(수치화) 했을 때, Red, Green, Blue에 대한 3개의 Layer를 쌓는다. 이를 Channer이라 한다.

 

 

Tensor를 가지고 놀아보자

# Tensor를 생성해보자.
# 1. 0으로 채워진 Tensor를 만들어보자
>>> tf.zeros(shape=(3, 10))
<tf.Tensor: shape=(3, 10), dtype=float32, numpy=
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>
       
       
# 2. 1로 채워진 Tensor를 만들어보자
>>> tf.ones(shape=(3,4), dtype = "int16")
<tf.Tensor: shape=(3, 4), dtype=int16, numpy=
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]], dtype=int16)>
       
       
# 3. 내가 원하는 상수로 채워진 Tensor를 만들어보자 
>>> tf.fill(dims=(3, 6), value=3)
<tf.Tensor: shape=(3, 6), dtype=int32, numpy=
array([[3, 3, 3, 3, 3, 3],
       [3, 3, 3, 3, 3, 3],
       [3, 3, 3, 3, 3, 3]])>
       
     
# 4. array를 만들듯이 Tensor를 만들어보자
>>> tf.constant([[1,3,5,7],[2,4,6,8]])
<tf.Tensor: shape=(2, 4), dtype=int32, numpy=
array([[1, 3, 5, 7],
       [2, 4, 6, 8]])>
       

# 5. array를 이용해서 Tensor를 만들어보자
>>> array1 = np.array([[1, 3, 5, 7], [2, 4, 6, 8]])
>>> tf.constant(array1)
<tf.Tensor: shape=(2, 4), dtype=int32, numpy=
array([[1, 3, 5, 7],
       [2, 4, 6, 8]])>


# 6. 패턴을 갖는 Tensor를 만들어보자
>>> tf.range(1, 20, 3)
<tf.Tensor: shape=(7,), dtype=int32, numpy=array([ 1,  4,  7, 10, 13, 16, 19])>
  • 별 설명 없이 여러 tensor를 만들어보았는데, 이를 보면 앞서 봤던 numpy의 array와 굉장히 유사하다는 생각이 들지 않는가?
  • 애초에 tf.constant() 함수에 array를 담으면 tensor가 되고 모든 형태의 array를 포함하는 것이 tensor이므로, 굳이 tensor를 공부하지 않아도 Numpy의 array만 잘 다루면 tensor를 무리 없이 쓸 수 있다.

 

# Tensor의 다양한 속성들을 뽑아보자
>>> TS1 = tf.constant([[1, 3, 5, 7, 9, 11], [2, 4, 6, 8, 10, 12], [2, 3, 5, 7, 11, 13]],
						dtype="float64")
>>> TS1
<tf.Tensor: shape=(3, 6), dtype=float64, numpy=
array([[ 1.,  3.,  5.,  7.,  9., 11.],
       [ 2.,  4.,  6.,  8., 10., 12.],
       [ 2.,  3.,  5.,  7., 11., 13.]])>
   
   
# 1. shape을 뽑아보자 
>>> TS1.shape
TensorShape([3, 6])


# 2. shape을 바꿔보자
>>> tf.reshape(TS1, shape=(2, 9))
<tf.Tensor: shape=(2, 9), dtype=float64, numpy=
array([[ 1.,  3.,  5.,  7.,  9., 11.,  2.,  4.,  6.],
       [ 8., 10., 12.,  2.,  3.,  5.,  7., 11., 13.]])>


# 3. dtype을 뽑아보자
>>> TS1.dtype
tf.float64


# 4. dtype을 바꿔보자
>>> tf.cast(TS1, dtype="int64")
<tf.Tensor: shape=(3, 6), dtype=int64, numpy=
array([[ 1,  3,  5,  7,  9, 11],
       [ 2,  4,  6,  8, 10, 12],
       [ 2,  3,  5,  7, 11, 13]], dtype=int64)>
  • 위 예제를 보면 굳이 tensor로 변환을 하지 않고, Numpy로 데이터 핸들링을 하는 것이 더 편하겠다는 생각이 들지 않는가?
  • tensor를 통해 사용할 수 있는 함수가 이외에도 수없이 많으나, 이에 시간을 할애하기보다는 scipy, pandas, matplotlib 등 다양한 모듈에서 폭넓게 사용할 수 있는 Numpy를 공부하는 것이 보다 효율적으로 판단되므로, 본 블로그에서는 tensor의 관련 함수는 여기까지만 정리하도록 하고 Numpy를 더 자세히 학습하도록 하겠다.

 

 

dtype

  • 위 예제를 보면 dtype="int64"와 같이 우리가 기존에 알고 있는 int 뒤에 숫자가 붙어 있는 것을 알 수 있다.
  • dtype은 float32, float64, int8, int16, int32, int64, unit8, string, bool 등이 있으며 뒤에 있는 숫자는 bit를 의미한다.
  • 종종 앞에 있는 dtype인 float은 일치하지만 bit가 일치하지 않아 오류가 발생하기도 하니, 혹여 dtype error가 뜨는 경우, 이를 확인해보도록 하자.

 

 

 

 지금까지 가볍게 tensor에 대해 학습해보았다. tensor는 Numpy의 array와 기능이 거의 일치하며, tensorflow로 학습을 할 때도 Numpy를 주로 사용하니 더 파고들진 않겠다.

 그러나 위에서 설명한 Tensor Rank 그림은 상당히 중요한 그림이므로, 꼭 숙지하도록 하자.

728x90
반응형
728x90
반응형

 

 Python, R과 같은 수많은 언어들에서 제일 중요한 건, 해당 언어에서 어떠한 자료형을 가지고 있느냐다.

 대부분의 오류는 사용하려는 api에 데이터를 담고 있는 형태(Type), 담겨 있는 데이터의 형태(Data type), 데이터의 구조(Shape)가 적합하지 않아 발생하며, 어지간해선 이를 해결하면 해결된다.

 성능향상 문제에서도 Type, Data type, Shape은 지대한 영향을 미치며, 이를 어떻게 가지고 노느냐에 따라서 같은 알고리즘도 전혀 다른 방식으로 접근할 수 있다.

 그러므로, Python 첫 번째 page에선 이에 대해 간략하게 살펴보도록 하자

  • Python을 사용하면서 느낀 중요한 부분에 대해 짚고 넘어갈 것이므로, 보다 상세한 설명을 원한다면 구글링 하길 바란다(분석가에게 제일 중요한 능력은 검색 능력이지 않는가!).
  • 일부 자료형은 설명하다보면 아주 깊게 들어가게 되므로, 자세한 설명은 뒤로 미루도록 하겠다.
  • Python을 사용하며, 데이터 분석에 유용하다고 느낀 Type을 위주로 설명한다.

 

 

 

Type

  1. scalar
  2. list
  3. array
  4. tensor
  5. dictionary
  6. DataFrame

 위 6가지 외에도 여러 Type이 존재하지만, 데이터 분석을 하면서, 숨 쉬듯 사용했던 Type 위주로 추려냈다.

 위 Type중 numpy의 array나 pandas의 DataFrame, tensorflow의 tensor 같이 해당 Type의 기능이 꽤 많아 제대로 이해하고 사용하려면 두꺼운 책 여러 권을 읽어야 하지만, 이는 뒤로 미뤄두고 오늘은 가볍게 설명해보자.

 

 

 

Scalar

 scalar를 극단적으로 단순하게 말해보면, 그냥 숫자나 문자가 딱 한 개 나오는 경우를 가리킨다. 여기서 문자라는 것은 눈에 보이기엔 문자처럼 보이지만 실제로는 숫자인데, 대체 이게 뭔소리냐 싶겠지만, 설명을 들어보면  꽤 쉽게 이해될 것이다.

 Python의 scalar에는 크게 4개의 자료형이 있다.

  1. int
  2. float
  3. None
  4. Boolean

 여기서 int는 정수, float는 소수, None은 값이 없음, Boolean은 True or False이다. 자, 이제 하나하나 설명해보도록 하자.

 

int(정수)

# int
>>> 1
1
  • 자, 숫자 1을 셀 안에 넣고 ctrl + enter를 입력하니 1이 반환되었다.
  • >>>는 입력한 코드
  • 아래에 >>> 없이 숫자만 나온 경우는 출력된 결과이다.
>>> a = 1
>>> print(a)
1
>>> print(type(a))
<class 'int'>
  • a에 1을 할당하고 print() 해보자
  • print()는 말 그대로 print(출력)하는 함수이다.
  • 참고로 주피터 노트북의 경우 셀의 맨 마지막 줄에 출력하고자 하는 함수를 입력하면, 해당 함수의 내용이 바로 출력 된다.
  • type()은 변수의 자료형을 확인하는 방법이다.
# int 함수를 이용하면 소수를 정수로 바꿀 수 있다.
# 소수 > 정수
>>> int(2.35)
2
# Boolean > 정수
>>> int(True)
1
# 문자 > 정수
>>> int("123")
123
  • int() 함수는 int가 될 수 있는 자료형을 int로 바꿔주는 역할을 한다.
  • ""나 ''는 문자를 의미하는데 담겨 있는 내용이 숫자인 경우엔 숫자로 바꿀 수 있다.
  • True의 경우 분명 문자인데 정수 1로 바뀌는 것이 이상하게 보일 수 있는데, 이는 꽤 재미난 성질이므로, 뒤에서 다시 언급하도록 하겠다.
  • 그러나, 정수로 형태를 변환시킬 수 없는 경우 ValueError가 뜨게 된다.
>>> int("scalar")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-45517d963ca8> in <module>
----> 1 int("scalar")

ValueError: invalid literal for int() with base 10: 'scalar'



>>> int("1.25")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-18-fb02bea94e38> in <module>
----> 1 int("1.25")

ValueError: invalid literal for int() with base 10: '1.25'



>>> int("True")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-19-c0bc75205372> in <module>
----> 1 int("True")

ValueError: invalid literal for int() with base 10: 'True'
  • "" 나 '' 안에 문자 혹은 소수가 들어가는 경우 ValueError가 발생한다.
  • 앞에서 1로 바뀌었던 True 역시 "True"로 들어가는 경우 ValueError가 발생한다.

 

 

float(소수)

# float
>>> print(1.25)
1.25

>>> b = 2.75
>>> print(b)
2.75

>>> print(type(b))
<class 'float'>

>>> print(float(10))
10.0
  • 말 그대로 소수이다.
  • int() 함수와 마찬가지로 float()를 하면 정수를 소수로 치환할 수 있다.
  • int()함수와 마찬가지로 float()이 될 수 없는 대상을 치환하려고 하는 경우 ValueError가 뜬다.
# 반올림, 올림, 버림을 해보자
>>> import numpy as np
>>> import math

>>> c = 15.62719

# 반올림
>>>print(np.round(c, 2))
>>>print(round(c, 3))
15.63
15.627

# 올림
>>> print(np.ceil(c))
>>> print(math.ceil(c))
16.0
16

# 버림
>>> print(np.trunc(c))
>>> print(math.trunc(c))
15.0
15
  • 반올림은 python의 기본 함수인 round가 있다.
  • 반올림, 올림, 내림은 주로 numpy, math 모듈의 함수를 이용한다.
  • numpy으로 충분하므로, 굳이 math 모듈을 가지고 올 필요는 없다.
  • import는 특정 모듈을 가지고 온다는 것을 의미하며, as는 그 모듈을 as 뒤에 있는 문자로 간단하게 표현하겠다는 것을 의미한다.
  • np.round(x, N): float x를 소수점 N 자리에서 반올림한다.
  • np.ceil(x): float x를 올림 한다(math.ceil()과 달리 결과는 float으로 반환).
  • np.trunc(x): float x를 내림한다(math.trunc()과 달리 결과는 float으로 반환).

 

 

None(값없음)

>>> None

>>> d = None
>>> print(d)
None
  • 말 그대로 값이 없다는 것을 의미한다.
  • 특정 변수를 미리 생성해놓고 추후 Data를 넣는 경우나, 결측 값 같이 값이 있어야 하는데 존재하지 않음을 나타낼 때 사용된다.

 

 

Boolean

>>> e = 10
>>> print(e == 10)
True

>>> print(e == 12)
False

>>> print(e != 10)
False

>>> if e == 10:
>>>     print("Go")
>>> else:
>>>     print("stop")

Go
  • Boolean 또는 Bool이라 불리는 scalar는 True와 False 두 개의 값으로 이루어져 있다.
  • if 문과 같이 True, False에 따라 다른 결과를 반환하는 경우나, 특정 값을 추출할 때 자주 사용된다.
>>> bool(1)
True

>>> bool(10.0)
True

>>> bool("abc")
True

>>> bool(0)
False

>>> bool(0.0)
False

>>> bool("")
False

>>> print(int(True))
1

>>>> print(int(False))
0
  • Boolean의 True는 1에 False는 0에 대응한다(이 성질을 잘 이용하면 코드를 아주 단순하게 만들 수 있다).
  • bool() 함수를 이용하면 0, 0.0, ""은 False에 나머지 경우는 True를 반환한다.

 

 

그 외

 위 내용을 보면 그렇다면 알파벳 같은 문자의 Type은 무엇일까? 하는 궁금증이 들 것이다.

>>> type("abc")
str

>>> type("123")
str
  • str이라 반환되며, 이는 string의 줄임말로 문자열을 의미한다. 문자와 숫자 Data는 그 접근 방향이 꽤나 다르므로, "Data가 딱 하나 있는 것들을 scalar라고 뭉뚱그려 말하지 않는구나!"라고 단순히 생각해보자.
  • scalar에 대한 심층적인 설명으로 들어가면, 내용이 상당히 길어지므로, 단순하게 숫자로 표현할 수 있거나 값이 존재하지 않는 경우를 scalar라고 생각하면 된다(상세한 내용은 위키피디아를 참조하자).
  • scalar는 뒤에서 배울 벡터에 원소가 하나만 있는 상태라고 생각하면 된다.

 

 

 이번 포스팅에서는 데이터의 Type과 scalar에 대해 알아보았다. 간략히 설명하려 했으나, 쓰다 보니 내용이 꽤 길어져 이 사람이 뭘 이야기하고 싶은 건가 싶을 수도 있으니, 다음 포스트부터는 좀 더 단순하게 적어보도록 하겠다.

 
728x90
반응형

+ Recent posts