In [1]:
# 필요한 라이브러리 불러오기
### pandas라는 라이브러리를 pd라고 줄여서 쓸거에요
import pandas as pd

### numpy라는 라이브러리를 np라고 줄여서 쓸거에요
import numpy as np

### sklearn이라는 큰 패키지가 있는데 여기서 데이터셋을 가져올거에요
from sklearn import datasets

#numpy 패키지가 없는 경우, 설치 명령어: pip install numpy
#pandas 패키지가 없는 경우, 설치 명령어: pip install pandas

혹시나 패키지가 없다고 한다면?¶

conda install (패키지명)¶
colab에서 설치하는 경우에는 ! pip install (패키지명) 혹은 $ pip install (패키지명)¶

왠만해서 우리가 오늘 사용한 패키지는 주피터와 코랩에 기본적으로 세팅이 되어있으니 걱정 X
세팅 안된경우 채팅으로 이야기해주세요

In [2]:
# 우리가 사용할 데이터셋을 불러옵니다
iris = datasets.load_iris()
iris

# 출력 결과를 보니 딕셔너리처럼 생긴 틀에 numpy array 형식의 데이터가 존재합니다
# numpy는 언제 사용하는 라이브러리이며 array는 뭘까요?
Out[2]:
{'data': array([[5.1, 3.5, 1.4, 0.2],
        [4.9, 3. , 1.4, 0.2],
        [4.7, 3.2, 1.3, 0.2],
        [4.6, 3.1, 1.5, 0.2],
        [5. , 3.6, 1.4, 0.2],
        [5.4, 3.9, 1.7, 0.4],
        [4.6, 3.4, 1.4, 0.3],
        [5. , 3.4, 1.5, 0.2],
        [4.4, 2.9, 1.4, 0.2],
        [4.9, 3.1, 1.5, 0.1],
        [5.4, 3.7, 1.5, 0.2],
        [4.8, 3.4, 1.6, 0.2],
        [4.8, 3. , 1.4, 0.1],
        [4.3, 3. , 1.1, 0.1],
        [5.8, 4. , 1.2, 0.2],
        [5.7, 4.4, 1.5, 0.4],
        [5.4, 3.9, 1.3, 0.4],
        [5.1, 3.5, 1.4, 0.3],
        [5.7, 3.8, 1.7, 0.3],
        [5.1, 3.8, 1.5, 0.3],
        [5.4, 3.4, 1.7, 0.2],
        [5.1, 3.7, 1.5, 0.4],
        [4.6, 3.6, 1. , 0.2],
        [5.1, 3.3, 1.7, 0.5],
        [4.8, 3.4, 1.9, 0.2],
        [5. , 3. , 1.6, 0.2],
        [5. , 3.4, 1.6, 0.4],
        [5.2, 3.5, 1.5, 0.2],
        [5.2, 3.4, 1.4, 0.2],
        [4.7, 3.2, 1.6, 0.2],
        [4.8, 3.1, 1.6, 0.2],
        [5.4, 3.4, 1.5, 0.4],
        [5.2, 4.1, 1.5, 0.1],
        [5.5, 4.2, 1.4, 0.2],
        [4.9, 3.1, 1.5, 0.2],
        [5. , 3.2, 1.2, 0.2],
        [5.5, 3.5, 1.3, 0.2],
        [4.9, 3.6, 1.4, 0.1],
        [4.4, 3. , 1.3, 0.2],
        [5.1, 3.4, 1.5, 0.2],
        [5. , 3.5, 1.3, 0.3],
        [4.5, 2.3, 1.3, 0.3],
        [4.4, 3.2, 1.3, 0.2],
        [5. , 3.5, 1.6, 0.6],
        [5.1, 3.8, 1.9, 0.4],
        [4.8, 3. , 1.4, 0.3],
        [5.1, 3.8, 1.6, 0.2],
        [4.6, 3.2, 1.4, 0.2],
        [5.3, 3.7, 1.5, 0.2],
        [5. , 3.3, 1.4, 0.2],
        [7. , 3.2, 4.7, 1.4],
        [6.4, 3.2, 4.5, 1.5],
        [6.9, 3.1, 4.9, 1.5],
        [5.5, 2.3, 4. , 1.3],
        [6.5, 2.8, 4.6, 1.5],
        [5.7, 2.8, 4.5, 1.3],
        [6.3, 3.3, 4.7, 1.6],
        [4.9, 2.4, 3.3, 1. ],
        [6.6, 2.9, 4.6, 1.3],
        [5.2, 2.7, 3.9, 1.4],
        [5. , 2. , 3.5, 1. ],
        [5.9, 3. , 4.2, 1.5],
        [6. , 2.2, 4. , 1. ],
        [6.1, 2.9, 4.7, 1.4],
        [5.6, 2.9, 3.6, 1.3],
        [6.7, 3.1, 4.4, 1.4],
        [5.6, 3. , 4.5, 1.5],
        [5.8, 2.7, 4.1, 1. ],
        [6.2, 2.2, 4.5, 1.5],
        [5.6, 2.5, 3.9, 1.1],
        [5.9, 3.2, 4.8, 1.8],
        [6.1, 2.8, 4. , 1.3],
        [6.3, 2.5, 4.9, 1.5],
        [6.1, 2.8, 4.7, 1.2],
        [6.4, 2.9, 4.3, 1.3],
        [6.6, 3. , 4.4, 1.4],
        [6.8, 2.8, 4.8, 1.4],
        [6.7, 3. , 5. , 1.7],
        [6. , 2.9, 4.5, 1.5],
        [5.7, 2.6, 3.5, 1. ],
        [5.5, 2.4, 3.8, 1.1],
        [5.5, 2.4, 3.7, 1. ],
        [5.8, 2.7, 3.9, 1.2],
        [6. , 2.7, 5.1, 1.6],
        [5.4, 3. , 4.5, 1.5],
        [6. , 3.4, 4.5, 1.6],
        [6.7, 3.1, 4.7, 1.5],
        [6.3, 2.3, 4.4, 1.3],
        [5.6, 3. , 4.1, 1.3],
        [5.5, 2.5, 4. , 1.3],
        [5.5, 2.6, 4.4, 1.2],
        [6.1, 3. , 4.6, 1.4],
        [5.8, 2.6, 4. , 1.2],
        [5. , 2.3, 3.3, 1. ],
        [5.6, 2.7, 4.2, 1.3],
        [5.7, 3. , 4.2, 1.2],
        [5.7, 2.9, 4.2, 1.3],
        [6.2, 2.9, 4.3, 1.3],
        [5.1, 2.5, 3. , 1.1],
        [5.7, 2.8, 4.1, 1.3],
        [6.3, 3.3, 6. , 2.5],
        [5.8, 2.7, 5.1, 1.9],
        [7.1, 3. , 5.9, 2.1],
        [6.3, 2.9, 5.6, 1.8],
        [6.5, 3. , 5.8, 2.2],
        [7.6, 3. , 6.6, 2.1],
        [4.9, 2.5, 4.5, 1.7],
        [7.3, 2.9, 6.3, 1.8],
        [6.7, 2.5, 5.8, 1.8],
        [7.2, 3.6, 6.1, 2.5],
        [6.5, 3.2, 5.1, 2. ],
        [6.4, 2.7, 5.3, 1.9],
        [6.8, 3. , 5.5, 2.1],
        [5.7, 2.5, 5. , 2. ],
        [5.8, 2.8, 5.1, 2.4],
        [6.4, 3.2, 5.3, 2.3],
        [6.5, 3. , 5.5, 1.8],
        [7.7, 3.8, 6.7, 2.2],
        [7.7, 2.6, 6.9, 2.3],
        [6. , 2.2, 5. , 1.5],
        [6.9, 3.2, 5.7, 2.3],
        [5.6, 2.8, 4.9, 2. ],
        [7.7, 2.8, 6.7, 2. ],
        [6.3, 2.7, 4.9, 1.8],
        [6.7, 3.3, 5.7, 2.1],
        [7.2, 3.2, 6. , 1.8],
        [6.2, 2.8, 4.8, 1.8],
        [6.1, 3. , 4.9, 1.8],
        [6.4, 2.8, 5.6, 2.1],
        [7.2, 3. , 5.8, 1.6],
        [7.4, 2.8, 6.1, 1.9],
        [7.9, 3.8, 6.4, 2. ],
        [6.4, 2.8, 5.6, 2.2],
        [6.3, 2.8, 5.1, 1.5],
        [6.1, 2.6, 5.6, 1.4],
        [7.7, 3. , 6.1, 2.3],
        [6.3, 3.4, 5.6, 2.4],
        [6.4, 3.1, 5.5, 1.8],
        [6. , 3. , 4.8, 1.8],
        [6.9, 3.1, 5.4, 2.1],
        [6.7, 3.1, 5.6, 2.4],
        [6.9, 3.1, 5.1, 2.3],
        [5.8, 2.7, 5.1, 1.9],
        [6.8, 3.2, 5.9, 2.3],
        [6.7, 3.3, 5.7, 2.5],
        [6.7, 3. , 5.2, 2.3],
        [6.3, 2.5, 5. , 1.9],
        [6.5, 3. , 5.2, 2. ],
        [6.2, 3.4, 5.4, 2.3],
        [5.9, 3. , 5.1, 1.8]]),
 'target': 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]),
 'frame': None,
 'target_names': array(['setosa', 'versicolor', 'virginica'], dtype='<U10'),
 'DESCR': '.. _iris_dataset:\n\nIris plants dataset\n--------------------\n\n**Data Set Characteristics:**\n\n    :Number of Instances: 150 (50 in each of three classes)\n    :Number of Attributes: 4 numeric, predictive attributes and the class\n    :Attribute Information:\n        - sepal length in cm\n        - sepal width in cm\n        - petal length in cm\n        - petal width in cm\n        - class:\n                - Iris-Setosa\n                - Iris-Versicolour\n                - Iris-Virginica\n                \n    :Summary Statistics:\n\n    ============== ==== ==== ======= ===== ====================\n                    Min  Max   Mean    SD   Class Correlation\n    ============== ==== ==== ======= ===== ====================\n    sepal length:   4.3  7.9   5.84   0.83    0.7826\n    sepal width:    2.0  4.4   3.05   0.43   -0.4194\n    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)\n    petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)\n    ============== ==== ==== ======= ===== ====================\n\n    :Missing Attribute Values: None\n    :Class Distribution: 33.3% for each of 3 classes.\n    :Creator: R.A. Fisher\n    :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)\n    :Date: July, 1988\n\nThe famous Iris database, first used by Sir R.A. Fisher. The dataset is taken\nfrom Fisher\'s paper. Note that it\'s the same as in R, but not as in the UCI\nMachine Learning Repository, which has two wrong data points.\n\nThis is perhaps the best known database to be found in the\npattern recognition literature.  Fisher\'s paper is a classic in the field and\nis referenced frequently to this day.  (See Duda & Hart, for example.)  The\ndata set contains 3 classes of 50 instances each, where each class refers to a\ntype of iris plant.  One class is linearly separable from the other 2; the\nlatter are NOT linearly separable from each other.\n\n.. topic:: References\n\n   - Fisher, R.A. "The use of multiple measurements in taxonomic problems"\n     Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions to\n     Mathematical Statistics" (John Wiley, NY, 1950).\n   - Duda, R.O., & Hart, P.E. (1973) Pattern Classification and Scene Analysis.\n     (Q327.D83) John Wiley & Sons.  ISBN 0-471-22361-1.  See page 218.\n   - Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System\n     Structure and Classification Rule for Recognition in Partially Exposed\n     Environments".  IEEE Transactions on Pattern Analysis and Machine\n     Intelligence, Vol. PAMI-2, No. 1, 67-71.\n   - Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule".  IEEE Transactions\n     on Information Theory, May 1972, 431-433.\n   - See also: 1988 MLC Proceedings, 54-64.  Cheeseman et al"s AUTOCLASS II\n     conceptual clustering system finds 3 classes in the data.\n   - Many, many more ...',
 'feature_names': ['sepal length (cm)',
  'sepal width (cm)',
  'petal length (cm)',
  'petal width (cm)'],
 'filename': 'iris.csv',
 'data_module': 'sklearn.datasets.data'}

1. numpy¶

  • 수치형 데이터들을 다룰 때 주로 사용하는 라이브러리
  • 다양한 수학적 연산을 할 수 있다는 특징이 있음
  • 특히 행렬 연산 및 다차원 배열의 연산에 특화되어있음
  • 여기서 array란?
    • 말그대로 숫자의 배열을 이야기
    • 리스트와 유사한 형태를 가짐
    • 리스트가 중첩되어있다면 이는 2차원 형태의 배열이라고 이야기함(aka 행렬)
    • 중첩리스트를 쓰면 되는거 아닌가요? 굳이 numpy array를 사용해야 하나?
      • numpy array가 중첩 리스트보다 데이터를 가공하고 처리하는데 훨씬 효율적
      • 중첩리스트를 사용하면 메모리 공간을 많이 차지해 시스템 과부하가 생길 수 있음
      • array는 더 효율적으로 메모리를 사용할 수 있음
In [3]:
# 데이터를 좀 더 분리해봅시다
iris.keys()
Out[3]:
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
  • data는 말 그대로 수치형 데이터들이 들어가있음
  • target은 각 행들이 어떤 품종인지 분류되어있는 데이터
  • target_names는 어떤 품종인지 텍스트로 알려주는 데이터
    • 'setosa' -> 0, 'versicolor' -> 1, 'virginica' -> 2
  • feature_names는 데이터를 2차원 테이블 형태로 불러왔을 때 column명을 의미
    • column = feature = X = 독립변수 = attribute
    • target = y = 종속변수 = class => 존재할 수도 존재하지 않을 수도 있음
    • 각 행은 record(DB에서 주로 사용) = 행 = row = instance
  • 다루지 않은 key는 필요 없어서 따로 다루지 않음!!
In [4]:
# 종합적인 데이터를 분리해 깔끔한 테이블형태로 바꿔보자
features = iris.data
feature_names = iris.feature_names
target = iris.target
target_names = iris.target_names

### 주피터 노트북 팁: 출력값 여러개 보고싶으면 필수적으로 print 써줘야 함
### print를 안쓰고, features.shape, feature_names...
### 엔터쳐서 나열해 작성한다면 가장 마지막에 작성된 변수의 출력값만 보여줌

# features는 행이 150개, 열이 4개인 형태의 데이터
print(features.shape)

# feature_names 또한 4개 -> features의 column명이 되어줄 것임
print(feature_names)

# target 또한 150개로 features의 행 개수와 똑같음
# -> 행 개수가 같기 때문에 데이터를 합치는데 문제가 없을 것으로 보임
print(target.shape)

# target_names는 이런게 있구나 확인해두자
print(target_names)
(150, 4)
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
(150,)
['setosa' 'versicolor' 'virginica']
  • .shape : 데이터의 형태를 알려줌
    • 배열 각 차원의 크기를 튜플 형태로 표현
    • n행과 m열의 행렬의 경우 (n,m) 형태의 튜플로 나타냄
  • .ndim : 배열의 차원 수
  • .dtype : 각 element의 타입 확인
  • .itemsize : 각 element의 타입의 bytes 크기 확인
  • .size : 전체 element 개수
  • iris.key : 딕셔너리 형태의 iris 데이터에서 key값을 이용해 데이터를 추출
    • 사실 여기서 iris 데이터는 완벽히 딕셔너리 자료형이라고 말할 수 없음
    • 형태만 비슷한 다른 자료형임
    • 이 자료형에서도 iris["data"]의 형태로 데이터를 추출할 수 있음
In [5]:
# 불러온 iris 데이터의 자료형을 확인한 결과 다음과 같다
type(iris)
Out[5]:
sklearn.utils._bunch.Bunch

2. Pandas¶

  • 우리가 이제 할 작업은 데이터를 합치는 작업
  • pandas의 DataFrame 형태로 만들어주는 세가지 방법에 대해 이야기하고자 함
  • pandas가 가지고 있는 다양한 기능들을 꺼내고자 한다면 "pd.~~~" ##### DataFrame이란?
  • pandas에서 제공하는 자료형 중 하나로 2차원형태의 데이터 구조
  • 일반적인 정형데이터의 구조와 같다고 생각하면 됨
  • 예) 엑셀(구글)시트
  • 행번호를 의미하는 index와 column명을 지정할 수 있음
  • 행별로 혹은 열별로 데이터를 추출할 수 있음
  • 특정 행에 있는 특정 열의 데이터 1개만 추출도 가능
  • 기타 등등 다양한 기능들이 있으며, 자주 보게 될 자료형 중 하나
  • 다른 형태의 데이터 타입을 DataFrame으로 전환 가능 ##### Series란?
  • pandas에서 제공하는 자료형 중 하나로 1차원 벡터 형태의 데이터 구조
    • 벡터란?
      • 일반적인 정의는 방향과 크기를 모두 가지고 있는 물리량
      • 벡터를 수학적으로 표현하면 [a b] 이렇게 표현
      • 여기서 데이터가 더 늘어나면 [a b c d e .. z]처럼 표현될 수 있음
      • 이런 1차원적인 배열을 일반적으로 벡터라고 이야기함
  • DataFrame과 다르게 column은 1개만 존재
  • index 따로 지정 가능
  • 한개의 column 이름을 따로 지정 불가능
In [6]:
# features 데이터와 target 데이터를 각각 데이터 프레임으로 만들어줌
# features 데이터프레임 만들기
features_df = pd.DataFrame(features, columns=feature_names)
features_df
Out[6]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
... ... ... ... ...
145 6.7 3.0 5.2 2.3
146 6.3 2.5 5.0 1.9
147 6.5 3.0 5.2 2.0
148 6.2 3.4 5.4 2.3
149 5.9 3.0 5.1 1.8

150 rows × 4 columns

In [7]:
# target series 만들기
target_se = pd.Series(target, name="target")
target_se
Out[7]:
0      0
1      0
2      0
3      0
4      0
      ..
145    2
146    2
147    2
148    2
149    2
Name: target, Length: 150, dtype: int64
In [8]:
# concat : 두개 이상의 데이터프레임 혹은 시리즈를 합치려는 경우
# 리스트로 합칠 데이터를 넣어줘야 함
# axis=1 : 열을 기준으로 데이터를 합침
data = pd.concat([features_df, target_se], axis=1)
data
Out[8]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2

150 rows × 5 columns

In [9]:
# axis=1이 없으면?
data = pd.concat([features_df, target_se])
data
Out[9]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) 0
0 5.1 3.5 1.4 0.2 NaN
1 4.9 3.0 1.4 0.2 NaN
2 4.7 3.2 1.3 0.2 NaN
3 4.6 3.1 1.5 0.2 NaN
4 5.0 3.6 1.4 0.2 NaN
... ... ... ... ... ...
145 NaN NaN NaN NaN 2.0
146 NaN NaN NaN NaN 2.0
147 NaN NaN NaN NaN 2.0
148 NaN NaN NaN NaN 2.0
149 NaN NaN NaN NaN 2.0

300 rows × 5 columns

merge : 판다스에서 제공하는 데이터를 병합하는 method 중 하나¶
  • how 옵션에 다양한 조건이 들어갈 수 있음

    • left: use only keys from left frame, similar to a SQL left outer join; preserve key order.

    • right: use only keys from right frame, similar to a SQL right outer join; preserve key order.

    • outer: use union of keys from both frames, similar to a SQL full outer join; sort keys lexicographically.

    • inner: use intersection of keys from both frames, similar to a SQL inner join; preserve the order of the left keys.

    • cross: creates the cartesian product from both frames, preserves the order of the left keys.

  • 더 자세한 내용은 공식 문서를 참조하세요
In [10]:
# 다른 방법: merge
# how='left' : 왼쪽(features_df)을 기준으로 파라미터로 넣은 series(target_se)를 합쳐라
# 파라미터(=매개변수)는 함수를 사용할 때 설정해주는 옵션들을 의미 ex) merge()에서 괄호 안에 들어가는 다양한 변수들
data = features_df.merge(target_se, how='left', left_index=True, right_index=True)
data
Out[10]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2

150 rows × 5 columns

In [11]:
# 또 다른방법: join
# merge와 비슷하나 파라미터가 조금 다름
data = features_df.join(target_se, how='left')
data
Out[11]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
... ... ... ... ... ...
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2

150 rows × 5 columns

3. EDA(Exploratory Data Analysis)¶

  • EDA란 탐색적 데이터 분석의 준말
  • 최종적으로 모델을 만들어 예측하기 전, 데이터의 특징들을 살펴보고 null값(비어있는 값)이나 이상치 등이 존재하는지 확인하고 전처리 해주는 과정을 이야기함
  • pandas의 다양한 기능들과 시각화 라이브러리를 사용할 예정임
In [12]:
# 데이터의 앞부분만 잘라 보기
# 괄호 안에 숫자를 지정해준다면 본인이 원하는 만큼 볼 수 있음
# 따로 숫자를 지정해주지 않는다면 5개의 행만 보여주는 것이 default
data.head()
Out[12]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0
3 4.6 3.1 1.5 0.2 0
4 5.0 3.6 1.4 0.2 0
In [13]:
# 데이터의 뒷부분만 잘라보기
# 괄호 안에 숫자를 지정해준다면 본인이 원하는 만큼 볼 수 있음
# 따로 숫자를 지정해주지 않는다면 5개의 행만 보여주는 것이 default
data.tail()
Out[13]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
145 6.7 3.0 5.2 2.3 2
146 6.3 2.5 5.0 1.9 2
147 6.5 3.0 5.2 2.0 2
148 6.2 3.4 5.4 2.3 2
149 5.9 3.0 5.1 1.8 2
In [14]:
# 데이터 랜덤으로 잘라 보기
# 괄호 안에 숫자를 지정해준다면 본인이 원하는 만큼 볼 수 있음
# 따로 숫자를 지정해주지 않는다면 1개의 행만 보여주는 것이 default
data.sample()
Out[14]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
56 6.3 3.3 4.7 1.6 1
In [15]:
# 가져오고 싶은 열 가져오기1
data['sepal length (cm)']
Out[15]:
0      5.1
1      4.9
2      4.7
3      4.6
4      5.0
      ... 
145    6.7
146    6.3
147    6.5
148    6.2
149    5.9
Name: sepal length (cm), Length: 150, dtype: float64
In [16]:
# 가져오고 싶은 열 가져오기2
data[['sepal length (cm)', 'sepal width (cm)']]
Out[16]:
sepal length (cm) sepal width (cm)
0 5.1 3.5
1 4.9 3.0
2 4.7 3.2
3 4.6 3.1
4 5.0 3.6
... ... ...
145 6.7 3.0
146 6.3 2.5
147 6.5 3.0
148 6.2 3.4
149 5.9 3.0

150 rows × 2 columns

  • df["name"] : name 열을 시리즈 형태로 가져오기
  • df[["name","origin"]] : name열과 origin열 가져오기
  • 여러 개의 열을 가져오고 싶으면 열을 대괄호로 한번 더 묶어줘야한다.
    • df["name","origin"]을 하게 되면 name과 origin을 두 개의 열이 아니라 하나의 열로 인식해서 오류가 나게 된다.
  • 대괄호 1개, 2개의 차이
    • 1개의 열을 가져올 때 대괄호 1개 사용 : 시리즈 형태로 가져온다.
    • 2개의 열을 가져올 때 대괄호 2개 사용 : 데이터 프레임 형태로 가져온다.
      • 이때, 1개의 열을 가져올 때 대괄호를 2개 사용해서 가져오면 데이터 프레임 형태로 가져올 수 있다!
In [17]:
# 가져오고 싶은 행 가져오기
data.loc[0]
Out[17]:
sepal length (cm)    5.1
sepal width (cm)     3.5
petal length (cm)    1.4
petal width (cm)     0.2
target               0.0
Name: 0, dtype: float64
In [18]:
# 가져오고 싶은 행 가져오기
data.loc[[0,1]]
Out[18]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
  • 하나의 행 가져올 때

    • df.loc[0] : 0번째 행을 가져온다는 의미
  • 두 개 이상의 행을 가져올 때

    • df.loc[0, 1] : 에러 발생
    • 행도 열과 마찬가지로 대괄호를 사용하여 가져와야한다. 👉 df.loc[[0,1]]
  • loc를 사용하여 행, 열 동시에 가져오기

    • 1쌍의 행, 열 가져오기

      • df.loc[0,"name"] : 이때는 대괄호를 1개만 써도 된다.
    • 여러 쌍의 행, 열 가져오기

      • 여러 개의 행과 열을 각각 대괄호로 묶고 전체를 대괄호로 묶기
      • ① 두 개의 행, 하나의 열 가져올 때 : df.loc[[0,1], ["name"]]

      • ② 두 개의 행, 두 개의 열 가져올 때 : df.loc[[0,1], ["name","origin"]]

loc & iloc 차이¶

  • loc
    • location의 약어
    • 데이터 프레임의 행 또는 컬럼의 label이나 boolean array로 인덱싱하는 방법
    • 사람이 읽을 수 있는 label 값으로 특정 값들을 골라오는 방법
  • iloc
    • integer location의 약어
    • 데이터 프레임의 행이나 컬럼의 인덱스 값으로 접근
In [19]:
# loc
#인덱스 이름이 0인 행 추출
data.loc[0]
Out[19]:
sepal length (cm)    5.1
sepal width (cm)     3.5
petal length (cm)    1.4
petal width (cm)     0.2
target               0.0
Name: 0, dtype: float64
In [20]:
# iloc
# 0번째 행에 있는 값들 추출
data.iloc[0]
Out[20]:
sepal length (cm)    5.1
sepal width (cm)     3.5
petal length (cm)    1.4
petal width (cm)     0.2
target               0.0
Name: 0, dtype: float64
In [21]:
# 데이터의 형태 알아보기
# 행 150개, 열 5개로 구성
data.shape
Out[21]:
(150, 5)
In [22]:
# 데이터의 전반적인 정보를 확인하자
# 컬럼명, 데이터타입과 null값이 아닌 데이터들을 모두 카운트했을 때의 정보를 알려줌
# non-null count가 총 행의 개수와 다르다면 null값이 존재하는 것임
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   sepal length (cm)  150 non-null    float64
 1   sepal width (cm)   150 non-null    float64
 2   petal length (cm)  150 non-null    float64
 3   petal width (cm)   150 non-null    float64
 4   target             150 non-null    int64  
dtypes: float64(4), int64(1)
memory usage: 6.0 KB
In [23]:
# 데이터의 기초통계량 알아보기
data.describe()
Out[23]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
count 150.000000 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.057333 3.758000 1.199333 1.000000
std 0.828066 0.435866 1.765298 0.762238 0.819232
min 4.300000 2.000000 1.000000 0.100000 0.000000
25% 5.100000 2.800000 1.600000 0.300000 0.000000
50% 5.800000 3.000000 4.350000 1.300000 1.000000
75% 6.400000 3.300000 5.100000 1.800000 2.000000
max 7.900000 4.400000 6.900000 2.500000 2.000000
  • count(빈도수) / mean(평균값) / std(표준편차) / min(최솟값) / 25% / 50% / 75% / max(최댓값)
  • 수치형 데이터만 표현된다.
    • 범주형 데이터(object)는 표현이 안 된다.
In [24]:
# null값이 존재하는지 확인
data.isnull()
Out[24]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 False False False False False
1 False False False False False
2 False False False False False
3 False False False False False
4 False False False False False
... ... ... ... ... ...
145 False False False False False
146 False False False False False
147 False False False False False
148 False False False False False
149 False False False False False

150 rows × 5 columns

In [25]:
# 이렇게 보면 정확하게 파악하기 힘드니 다음과 같이 확인해보자
data.isnull().sum()
Out[25]:
sepal length (cm)    0
sepal width (cm)     0
petal length (cm)    0
petal width (cm)     0
target               0
dtype: int64
  • .isna / .isnull : 결측치 확인

    • True인 값이 결측치이다.
  • .isnull().sum() : .isnull()에서 출력되는 값들의 합계

    • .isnull().sum()을 했을 때 1이상이 나오면 True가 포함된 것이므로 결측치가 있는 열이고, 몇 개가 있는지 알 수 있다.
  • .isnull().mean() : 결측치 비율 확인 함수

  • .isnull().mean() * 100 : 백분위로 확인 가능

null값이 존재하지 않으니 전반적인 데이터의 분포를 시각화 해보자¶

  • 이전까지의 과정은 pandas에서 제공하는 함수들을 이용해 수치적으로 데이터를 알아보았음
  • 데이터의 정보
    • sepal: 꽃받침
    • petal: 꽃잎
  • matplotlib과 seaborn을 이용해 시각화해보자
In [26]:
import matplotlib.pyplot as plt
import seaborn as sns
In [28]:
# boxplot을 이용해 각 컬럼별로 데이터의 분포를 확인해보자(1)
sns.boxplot(x=data["target"], y=data["sepal length (cm)"], data=data)
plt.title('col')
plt.show
Out[28]:
<function matplotlib.pyplot.show(close=None, block=None)>
In [30]:
# boxplot을 이용해 각 컬럼별로 데이터의 분포를 확인해보자(2)
sns.boxplot(x=data["target"], y=data["sepal width (cm)"], data=data)
plt.title('col')
plt.show
Out[30]:
<function matplotlib.pyplot.show(close=None, block=None)>
In [31]:
# boxplot을 이용해 각 컬럼별로 데이터의 분포를 확인해보자(3)
sns.boxplot(x=data["target"], y=data["petal length (cm)"], data=data)
plt.title('col')
plt.show
Out[31]:
<function matplotlib.pyplot.show(close=None, block=None)>
In [32]:
# boxplot을 이용해 각 컬럼별로 데이터의 분포를 확인해보자(4)
sns.boxplot(x=data["target"], y=data["petal width (cm)"], data=data)
plt.title('col')
plt.show
Out[32]:
<function matplotlib.pyplot.show(close=None, block=None)>
In [36]:
# scatterplot을 이용해 꽃받침 길이와 꽃받침 너비를 비교해보자
sns.scatterplot(x='sepal length (cm)', y='sepal width (cm)',
                hue='target', data=data )

# 변수 설명 밖으로 내보내기
plt.legend(bbox_to_anchor=(1, 1), loc=2)

plt.show()
In [37]:
# scatterplot을 이용해 꽃잎 길이와 꽃잎 너비를 비교해보자
sns.scatterplot(x='petal length (cm)', y='petal width (cm)',
                hue='target', data=data )

# 변수 설명 밖으로 내보내기
plt.legend(bbox_to_anchor=(1, 1), loc=2)

plt.show()
In [38]:
# 히스토그램을 사용해 다양한 열에 대한 데이터 분포를 확인해보자
fig, axes = plt.subplots(2, 2, figsize=(10,10))

axes[0,0].set_title("Sepal Length")
axes[0,0].hist(data['sepal length (cm)'], bins=7)

axes[0,1].set_title("Sepal Width")
axes[0,1].hist(data['sepal width (cm)'], bins=5);

axes[1,0].set_title("Petal Length")
axes[1,0].hist(data['petal length (cm)'], bins=6);

axes[1,1].set_title("Petal Width")
axes[1,1].hist(data['petal width (cm)'], bins=6);
In [44]:
# .corr() : 데이터 프레임에 있는 모든 열의 쌍별 상관 관계를 찾을 수 있다.
data.corr(method = 'pearson')
Out[44]:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
sepal length (cm) 1.000000 -0.117570 0.871754 0.817941 0.782561
sepal width (cm) -0.117570 1.000000 -0.428440 -0.366126 -0.426658
petal length (cm) 0.871754 -0.428440 1.000000 0.962865 0.949035
petal width (cm) 0.817941 -0.366126 0.962865 1.000000 0.956547
target 0.782561 -0.426658 0.949035 0.956547 1.000000
In [45]:
# 히트맵을 이용해 모든 수치 변수 간의 상관 관계를 시각화해서 살펴보자
sns.heatmap(data.corr(method='pearson').drop(
  ['target'], axis=1).drop(['target'], axis=0),
            annot = True);

plt.show()

그래프 종류¶

  • plot(x,y) : 기본 x-y 선그래프

  • scatter(x,y) : 산점도

  • hist(x) : 히스토그램

  • hist2d(x, y) : 2차원 히스토그램

  • boxplot(x) : 박스플롯

그래프 구성 요소¶

  • title : 그림의 제목

  • axis: 그래프의 축, x, y, z (3D plots)

  • label : 축라벨(xlabel, ylabel)

  • tick (tick mark) : 축의 눈금표시

  • tick label : 그래프 축의 눈금표시에 붙어있는 라벨

  • symbol : 점도표, 산점도에서의 점의 모양

  • size : 점 또는 문자의 크기

  • linestyle : 선의 종류, 실선(solid), 점선(dotted), …

  • linewidth : 선의 굵기

  • alpha : 투명도, 도형 내부의 색깔에 대한 투명도, 0(완전투명) ~ 1(불투명)

  • legend : 범례표시

  • annotation : 그래프 위의 주석문

  • padding : 패딩, 축과 축이름의 사이