R과 Python에서 데이터 프레임 (I)

2020-08-10

개요

데이터 프레임

데이터 프레임은 데이터 과학에서 자료(data)들의 기본 구조이며, 행과 열을 갖고 있는 테이블 형태입니다. 행(row)은 관찰하고자 하는 대상1이며 열(column)은 각 관찰 대상들로 부터 측정하고자 하는 속성2들의 집합입니다.

만일 20개의 문항으로 이뤄진 설문지를 100명으로부터 응답을 Excel등을 이용하여 디지털로 기록할 경우 여러가지 방법이 있지만, 대부분 100개의 행과 20개의 열을 갖는 표 형태로 저장하고 이를 R이나 Python에서 작업하기 용이하도록 하는 구조 입니다.

R과 Python에서의 데이터 프레임

R은 통계를 위해 개발된 언어로 데이터 프레임을 언어 자체에서 지원하며, 자주 사용하는 데이터 프레임에 대해 다양한 패키지들이 존재3하여 더욱 편리한 환경을 제공해 주고 있습니다.

Python의 경우 범용 언어로 리스트, 튜플, 딕셔너리 등의 자료구조를 제공하고 있으나, 데이터 프레임을 언어 자체에서 지원하지는 않습니다4. 대신 pandas라는 데이터 과학을 위한 유용한 모듈이 있어 이를 통해 데이터 프레임을 다룰 수 있습니다5.

데이터 프레임 작업하기

데이터 설명

자료는 기상청 기상자료개방포털에서 기후통계분석 메뉴를 통해 다운로드 받은 춘천시의 1966년 1월 1일부터 2020년 8월 8일까지6 매일 최고기온, 최저기온 및 평균 기온을 저장한 데이터를 사용하겠습니다.

데이터 읽기 : csv 파일

먼저 csv7로 저장된 데이터 파일을 읽어오겠습니다.

제공한 파일은 앞 7줄까지 설명 글이 있으며 실 데이터는 8줄부터 시작합니다.

해당 데이터 앞 일부분

해당 데이터 앞 일부분

이 파일을 읽어오기 위해 R의 경우 tidyverse 패키지에 함께 있는 readr 패키지의 read_csv()를 사용할 것이고, Python의 경우 pandas에서 제공하는 메소드 read_csv()를 이용할 것입니다.

R

자료를 읽어와 변수 temp_cc로 저장하고 데이터 프레임의 행과 열의 수를 세어보았습니다.

  • read_csv() 함수의 인수
    • skip : 지정한 파일에서 데이터 영역으로 읽지 않고 건너뛸 줄 수를 지정합니다. 이 예에서 앞의 7줄은 데이터 영역이 아니므로 7을 전달합니다.
    • locale : 텍스트 파일의 저장 인코딩이 utf-8 이 아닐경우 저장된 인코딩을 지정합니다. 앞서 데이터는 euc-kr로 인코딩된 파일로 이를 지정하였으며, locale 정보로 우리나라를 나타내는 ko를 함께 전달합니다. (이 경우 시간, 통화 등의 정보를 우리나라에 맞춰줍니다.)
  • 함수 str() : R에서 자료의 구조(structure)를 보여주는 함수입니다.
library( tidyverse )

temp_cc <- read_csv("./data/temp_cc_195007_202008.csv", skip=7, locale=locale("ko", encoding="euc-kr"))

str(temp_cc)
## tibble [19,944 x 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ 날짜        : Date[1:19944], format: "1966-01-01" "1966-01-02" ...
##  $ 지점        : num [1:19944] 101 101 101 101 101 101 101 101 101 101 ...
##  $ 평균기온(℃): num [1:19944] -10.1 -8.9 -5.3 -3.3 -6.1 -2.8 -4.3 -7.1 -4.6 -3 ...
##  $ 최저기온(℃): num [1:19944] -16.9 -15.4 -10.3 -7.7 -12.7 -7.1 -12 -14.3 -9.9 -6.5 ...
##  $ 최고기온(℃): num [1:19944] -1.4 -0.1 -0.2 1.2 1.9 3.9 2.1 -0.6 2.3 4.2 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   날짜 = col_date(format = ""),
##   ..   지점 = col_double(),
##   ..   `평균기온(℃)` = col_double(),
##   ..   `최저기온(℃)` = col_double(),
##   ..   `최고기온(℃)` = col_double()
##   .. )
nrow(temp_cc)
## [1] 19944
ncol(temp_cc)
## [1] 5

Python

마찬가지로 변수 temp_cc2로 저장하고 행과 열의 수를 세어 보았습니다.

  • read_csv() 메소드의 인수
    • skiprows : 앞서 R의 read_csv()의 인수 skip과 동일합니다.
    • encoding : R과 동일한 기능입니다만, euc-kr8이 아닌 CP9499를 전달합니다. euc-kr은 한글 지원을 위해 유닉스 계열에서 나온 완성형 코드 조합이며 CP949는 Microsoft Windows에서 한글 인코딩을 위해 사용하는 확장완성형 입니다. 우선 CP949는 우리나라의 기존 euc-kr을 확장한 것이라고 생각하시면 좋을 것 같습니다.
  • 메소드 info() : Python에서는 해당 객체의 정보를 보여주는 메소드로 데이터 프레임의 경우 R의 str()과 동일하게 열 이름과 각 열의 유형을 보여줍니다.
import pandas as pd

temp_cc2 = pd.read_csv("./data/temp_cc_195007_202008.csv", skiprows=7, encoding="CP949")

temp_cc2.info()
## <class 'pandas.core.frame.DataFrame'>
## RangeIndex: 19944 entries, 0 to 19943
## Data columns (total 5 columns):
##  #   Column   Non-Null Count  Dtype  
## ---  ------   --------------  -----  
##  0   날짜       19944 non-null  object 
##  1   지점       19944 non-null  int64  
##  2   평균기온(℃)  19943 non-null  float64
##  3   최저기온(℃)  19943 non-null  float64
##  4   최고기온(℃)  19943 non-null  float64
## dtypes: float64(3), int64(1), object(1)
## memory usage: 779.2+ KB
len(temp_cc2.index)        # len(temp_cc)
## 19944
len(temp_cc2.columns)
## 5

열의 이름 바꾸기

데이터 파일로 부터 열의 이름은 날짜, 지점, 평균기온(℃), 최저기온(℃), 최고기온(℃) 입니다. 이를 변경해 봅시다.

R

R의 경우 해당 데이터 프레임의 열 이름을 담고 있는 names 속성10을 다루는 함수 names()를 이용합니다.

  • names()함수는 열의 이름을 출력해 줍니다.
  • names()함수에 벡터를 할당하면 해당 위치의 열 이름을 변경합니다.
names(temp_cc)
## [1] "날짜"         "지점"         "평균기온(℃)" "최저기온(℃)" "최고기온(℃)"
names(temp_cc) <- c("date", "pointID", "mean_temp", "min_temp", "max_temp")
names(temp_cc)
## [1] "date"      "pointID"   "mean_temp" "min_temp"  "max_temp"

Python

Python의 경우 읽어 온 데이터는 데이터 프레임 객체이며11 해당 객체의 속성과 메소드를 이용합니다.

  • 열 이름을 출력을 위해 열 속성(.columns)의 값(.values)을 리스트로 출력하는 메소드 tolist()를 이용합니다.
  • 열 이름 변경은 메소드 rename()을 이용합니다.
    • 인수 columns에 기존 열이름과 새로운 열이름의 딕셔너리를 전달합니다.
    • 데이터 프레임 자체에 적용하기 위해 인수 inplace에 값 True를 전달합니다.
temp_cc2.columns.values.tolist()
## ['날짜', '지점', '평균기온(℃)', '최저기온(℃)', '최고기온(℃)']
temp_cc2.rename(columns={"날짜": "date", "지점": "pointID", "평균기온(℃)": "mean_temp", "최저기온(℃)": "min_temp", "최고기온(℃)": "max_temp"}, inplace=True)
temp_cc2.columns.values.tolist()
## ['date', 'pointID', 'mean_temp', 'min_temp', 'max_temp']

  1. 데이터베이스에서 행은 Record라 부르며, 이 행들의 모임들을 Record Set이라고 부른다. 즉, 데이터 베이스에서는 Record Set 이라고도 합니다.

  2. 색연필을 제작하는 공장을 예를 들어 봅시다. 제작한 제품중 임의로 10개의 연필을 선택하여 제품이 잘 생산되었는지 검사할 경우 관찰 대상은 10개의 연필이며, 각 연필별로 굵기, 색상, 두께 등은 관찰하고자 하는 속성입니다. 이제 이를 저장하면 10개의 행을 가지며 굵기, 색상, 두께 3개의 열을 갖는 구조로 저장합니다.

  3. 대표적으로 Rstudio 개발팀에서 제공하는 tidyverse 패키지에 포함되어 있는 tibble 패키지

  4. 기본적으로 Python에서 아예 사용할 수 없다는 것이 아니라, 데이터 프레임이라는 형태를 직접 하지는 않는다는 의미입니다. 소개하는 pandas가 제공하는 데이터 프레임을 사용하지 않을 경우 Python에서는 열들을 개별 리스트로 접근하여 데이터를 처리할 수 있습니다.

  5. pandas 홈페이지

  6. 설정구간을 1950년 1월 1일로 하였으나, 춘천의 경우 1966년 1월 1일 자료부터 존재하며, 기상자료개방포털에서 춘천은 북춘천과 춘천 두 군데가 존재하며 이중 춘천으로 지역을 설정하였습니다.

  7. Comma Separated Value의 약자로 열 구분을 콤마(,)로 하는 데이터를 일반 텍스트 파일로 저장하는 대표적인 방법입니다.

  8. https://ko.wikipedia.org/wiki/EUC-KR

  9. https://ko.wikipedia.org/wiki/%EC%BD%94%EB%93%9C_%ED%8E%98%EC%9D%B4%EC%A7%80_949

  10. R에서 다음을 입력해 보세요. attr( temp_cc, “names” )

  11. R도 마찬가지로 객체로 다룹니다.

R & PythonRPythonDataframe

공공데이터 포털에서 OpenAPI 이용하기(작성중)

정규표현식 - 첫번째