1. Intro

지난 시간에는 열(=Column)을 다루는 것을 배웠다. 구체적으로는 열을 선택하는 방법, 추가하는 방법, 삭제하는 방법을 배웠다. 이번에는 행을 다루는 것을 배워보도록 해보자. 


[지난 글]

2019/11/12 - [Python/[Python] 데이터 전처리] - [파이썬] 판다스 활용 데이터 전처리 - 행 다루기


우선 지난 챕터와 마찬가지로 연습용 데이터를 만들어보도록 하자. 학생들의 이름을 변수로 추가하도록 한다. 

import pandas as pd
exam_dic = {'이름' : ['Evan', 'Chloe', 'Alice', 'John'],
            '국어' : [80, 70, 90, 87], 
            '영어' : [100, 80, 50, 90], 
            '수학' : [85, 75, 65, 100], 
            '과학' : [89, 67, 90, 85]}

data = pd.DataFrame(exam_dic)

print(data)
      이름  국어   영어   수학  과학
0   Evan  80  100   85  89
1  Chloe  70   80   75  67
2  Alice  90   50   65  90
3   John  87   90  100  85

 

2. 행 다루기

행을 다루는 방법은 여러가지가 있는데, 대표적으로 말하면 크게 3가지가 존재한다. 
- 행 선택(Selection)
- 행 추가(Addition)
- 행 삭제(Deletion)

이제 본격적으로 차례대로 하나씩 진행하도록 해본다.

2.1 행 선택

판다스에서 행을 선택하는 방법은 loc[]을 사용한다. 먼저 `loc[]`을 사용하여 Chloe을 선택 해보자.

data.loc[1]
이름    Chloe
국어       70
영어       80
수학       75
과학       67
Name: 1, dtype: object

이번에는 Alice를 선택해보자. 

data.loc[2]
이름    Alice
국어       90
영어       50
수학       65
과학       90
Name: 2, dtype: object

위 데이터의 문제점은 이름으로 행을 추출하는 것이 아니라 숫자로 선택해야 한다는 점이다. 데이터가 많아지면 특정행을 추출하기가 매우 어려워지기 때문에 데이터에 '이름'열을 새로운 인덱스로 지정하겠다. 이 때에는 set_index('새로운_인덱스_열', inplace=True)을 추가하면 된다.

data.set_index('이름', inplace=True)
print(data)
       국어   영어   수학  과학
이름                     
Evan   80  100   85  89
Chloe  70   80   75  67
Alice  90   50   65  90
John   87   90  100  85

이름이 새로운 인덱스로 변환된 것을 확인할 수 있다. 이제 다시 ChloeAlice를 선택해본다.

data.loc['Chloe']
국어    70
영어    80
수학    75
과학    67
Name: Chloe, dtype: int64
data.loc['Alice']
국어    90
영어    50
수학    65
과학    90
Name: Alice, dtype: int64

만약 2개 이상의 행을 선택하고 싶다면 data.loc[['행이름1', '행이름2', ..., '행이름N']]와 같은 형태로 지정하면 이번에는 시리즈 객체가 아닌 데이터프레임으로 반환한다. 

Chloe와 Alice를 동시에 선택하도록 해본다. 코드로 확인해보자. 

data.loc[['Chloe', 'Alice']]
        국어	영어	수학	과학
이름				
Chloe	70	80	75	67
Alice	90	50	65	90

위에서 보는 것처럼 데이터프레임으로 반환된 것을 볼 수 있다. 범위 슬라이싱과 같은 고급 기술도 있지만, 이 부분은 실무 데이터와 함께 적용하는 것으로 일단 남겨둔다. 

2.2 행 추가
열을 추가하는 것은 엑셀을 쉽게 떠올리면 매우 쉽다. 간단하게 문법을 소개하면 data['새로운 행 이름'] = 데이터 값 와 같으며, 이 때 데이터 값을 잘 다뤄야 한다. 

이번에는 Chris라는 학생을 추가하도록 해본다. 이 때 주의해야 하는 점은 새로운 행을 추가할 때는 data.loc['새로운_인덱스_이름']으로 시작해야 한다는 점이다. 그리고, 입력값의 열의 이름이 동일한지 확인해봐야 한다. 

data.loc['Chris'] = [90, 85, 80, 50]
print(data)
       국어   영어   수학  과학
이름                     
Evan   80  100   85  89
Chloe  70   80   75  67
Alice  90   50   65  90
John   87   90  100  85
Chris  90   85   80  50

약에 새로운 데이터프레임이 있다고 한다면 어떻게 합쳐야 할까? 이 때에는 pandas.concat([data, new_row])과 같은 형태로 진행하면 된다. 두개 Row가 있는 데이터프레임을 만든 후 행을 합치는 것을 진행해보겠다.

exam_dic2 = {'국어' : [80, 70], 
            '영어' : [100, 80], 
            '수학' : [85, 75], 
            '과학' : [89, 67]}

new_row = pd.DataFrame(exam_dic2, index=['대한이', '민국'])

data2 = pd.concat([data, new_row])
print(data2)
       국어   영어   수학  과학
Evan   80  100   85  89
Chloe  70   80   75  67
Alice  90   50   65  90
John   87   90  100  85
Chris  90   85   80  50
대한이    80  100   85  89
민국     70   80   75  67

2.3 행 삭제
행을 삭제하는 방법은 drop함수를 사용하는 방법이다. drop 함수를 사용 시, 각 행의 이름 또는 위치 숫자를 입력하여 제거하면 된다. Evan과 Chloe 행을 제거해보자.

data.drop(["Evan", "Chloe"], inplace = True) 
  
data 
	    국어	영어	수학	과학
이름				
Alice	90	50	65	90
John	87	90	100	85
Chris	90	85	80	50

지금까지 데이터프레임의 행(=Row)을 다루는 가장 기본적인 과정을 다루었다. 물론, 실무에서는 고급기술이 더 많이 사용되기는 하지만, 언제나 기초가 중요하기 때문에 기본적인 함수의 사용법에 대해 익히기를 바란다. 

 

다음 시간에는 행과 열을 동시에 사용하여 데이터를 다루는 방법을 배우도록 하겠다.

 

 

 

 

 

 

 

 

 

 

데이터프레임은 2차원 배열의 행과 열로 구성되어져 있다. 대부분의 사람들이 알고 있는 마이크로소프트사의 EXCEL, SQL Table 등을 생각하면 데이터프레임을 쉽게 이해할 수 있다. 판다스에서 가장 많이 사용되는 객체이며, 실제 파이썬을 활용한 데이터 분석을 하고 싶다면 필수적으로 알아야 하는 내용이다. 기본적으로 Python은 행렬 연산에 최적화된 언어라고 할 수 있지만, 판다스 라이브러리는 R의 데이터프레임에서 유래했다고 알려져 있다. 

[그림 1-1] 엑셀의 테이블 예시

 

여기서 잠깐! 초급자 또는 입문자들이 가장 궁금해하는 것 중의 하나가 R과 Python에 대한 비교가 아닐까 싶다. 통계/컴공 비전공자인 필자가 경험적으로 말씀 드리면 프로그래밍 기초가 전혀 없는 분들 중, 엑셀보다 빠른 데이터 전처리와 간단한 그래프를 그리는 것이 주목적이라면 여전히 R의 데이터프레임은 강력한 무기다. 간단하게 비교를 하자면, R의 대부분은 패키지는 데이터프레임이 기본 객체라고 봐도 무방하다. 그러나 파이썬은 웹개발이 주 언어이기 때문에 쉽게 접근하기가 힘들다. 인덱스, 딕셔너리, 행렬 등 매우 다양한 객체가 존재하기 때문에 이에 대한 인식은 알고서 출발해야 한다. 이 부분 때문에 조금 힘들고 난해할 수 있다. 그러나 데이터를 활용하여 프로그램을 개발하고 싶다면 이 때에는 Python이 가장 강력한 무기가 될 수 있다.

 

다시 본론으로 돌아오면, 아래 그림에서 설명하는 것처럼, 여러개의 시리즈들이 한데 모여서 데이터프레임을 이루는 구조가 데이터프레임이라고 할 수 있다.  

[그림 1-2] 시리즈와 데이터프레임 구조

시리즈가 모여서 데이터프레임이 만들어진다고 보면 더 좋을 듯 하다. 이 때, 데이터프레임의 열은 각각 시리즈의 객체이다. 우선, 판다스를 활용하여 간단하게 데이터프레임을 만들어 본다.

 

1. 딕셔너리에서 데이터프레임으로의 변환

딕셔너리에서 데이터프레임으로 변환하도록 한다. 아래 샘플코드를 확인해보자. 

dic_data = {'country': ['벨기에', '인도', '브라질'], 
        'capital': ['브뤼셀', '뉴델리', '브라질리아'], 
        'population': [11190846, 1303171035, 207847528]}

df = pd.DataFrame(dic_data)
print(df)
  country capital  population
0     벨기에     브뤼셀    11190846
1      인도     뉴델리  1303171035
2     브라질   브라질리아   207847528

'country', 'capital', 'population'은 열이름과 관련이 있는 것을 볼 수가 있다. 또한 자동적으로 행 인덱스가 0부터 생성됨을 볼수가 있다.

2. 시리즈에서 데이터프레임으로의 변환

이번에는 시리즈에서 데이터프레임으로 변환한다. 아래 샘플코드를 확인해보자.

series = {'one': pd.Series([1., 2., 3.], index=['a', 'b', 'c']), 
          'two': pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(series)
print(df)
   one  two
a  1.0  1.0
b  2.0  2.0
c  3.0  3.0
d  NaN  4.0

한가지 특이점은 각 컬럼마다 값이 달라도 에러가 발생하지는 않고, 다만 NaN이 작성되는 것을 볼 수가 있다.

3. ndArrays & Lists에서 데이터프레임으로의 변환

파이썬은 행렬과 리스트로 작성되는 코드가 많다. ndArrays에서 데이터프레임으로 변환 시, 특정 열(=column)에 결측치가 있으면 에러가 반환된다. 먼저 정상적인 코드를 확인한다.

ndArrays = {'one': [1., 2., 3., 4.], 
            'two': [4., 3., 2., 1.]}

pd.DataFrame(ndArrays)
   one  two
0  1.0  4.0
1  2.0  3.0
2  3.0  2.0
3  4.0  1.0

다음은 결측치가 발생한 코드를 확인한다. 아래코드에서 보는 것처럼 ValueError: arrays must all be same length 에러가 발생하는 것을 확인할 수 있다. (실제 에러코드가 발생하는지 확인해본다!)

ndArrays = {'one': [1., 2., 3., 4.], 
            'two': [4., 3., 2.]}

pd.DataFrame(ndArrays)

[그림 1-3] ndArrays에서 데이터프레임 변환 에러 발생 예시

위 코드에서 알 수 있는 것처럼, 딕셔너리 또는 시리즈 객체에서 데이터프레임으로 변환하는 경우 NaN을 반환하지만 데이터프레임으로 변환이 가능했다. 그러나 ndArrays의 경우 데이터프레임 객체 생성이 되지 않기 때문에, 데이터프레임으로 변환할 경우, 해당 객체가 ndArrays인지 우선 확인이 필요하다. 

 

다음 시간에는 생성된 데이터프레임에서 행과 열을 추출, 삭제, 추가와 관련된 내용을 담을 예정이다. 

+ Recent posts