DataFrame이란 무엇일까요?
Pandas의 DataFrame은 스프레드시트나 데이터베이스처럼 행(row)과 열(column)로 구성된 표 형태의 데이터 구조입니다. 즉, DataFrame은 2차원(2D) 객체입니다.
1D와 2D라는 용어가 헷갈리나요?
1차원(Series)과 2차원(DataFrame)의 핵심 차이는 특정 데이터 지점에 도달하기 위해 필요한 참조 정보의 개수입니다. Series에서 값을 추출하려면 행 인덱스 하나만 있으면 됩니다.
반면 표 형태인 DataFrame에서는 한 가지 참조 정보만으로는 부족하며, 행 값과 열 값의 교차점을 알아야 원하는 데이터에 접근할 수 있습니다.
CSV 파일로 Pandas DataFrame 만들기
아래 코드는 CSV 파일로부터 Pandas DataFrame을 생성하는 예시입니다. .read_csv() 메서드는 기본적으로 DataFrame을 반환합니다. 영화 데이터셋은 kaggle.com에서 "movies"로 검색해 다운로드할 수 있습니다.
"""Script : Create a Pandas DataFrame from a csv file."""
import pandas as pd
movies_dataset = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv")
# 1. 객체 타입 확인
type(movies_dataset)
# 2. 상위 5개 레코드를 표 형태로 출력
movies_dataset.head(5)| budget | id | original_language | original_title | popularity | release_date | revenue | runtime | status | title | vote_average | vote_count | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 237000000 | 19995 | en | Avatar | 150.437577 | 10/12/2009 | 2787965087 | 162.0 | Released | Avatar | 7.2 | 11800 |
| 1 | 300000000 | 285 | en | Pirates of the Caribbean: At World's End | 139.082615 | 19/05/2007 | 961000000 | 169.0 | Released | Pirates of the Caribbean: At World's End | 6.9 | 4500 |
| 2 | 245000000 | 206647 | en | Spectre | 107.376788 | 26/10/2015 | 880674609 | 148.0 | Released | Spectre | 6.3 | 4466 |
| 3 | 250000000 | 49026 | en | The Dark Knight Rises | 112.312950 | 16/07/2012 | 1084939099 | 165.0 | Released | The Dark Knight Rises | 7.6 | 9106 |
| 4 | 260000000 | 49529 | en | John Carter | 43.926995 | 7/03/2012 | 284139100 | 132.0 | Released | John Carter | 6.1 | 2124 |
단일 열 선택하기
인덱싱 연산자([])에 열 이름을 문자열 또는 리스트로 전달하면 해당 열의 값을 Series 또는 DataFrame 형태로 얻을 수 있습니다.
열 이름을 문자열로 전달하면 결과는 Series가 되고, 열 이름 하나만 담긴 리스트를 전달하면 결과는 DataFrame이 됩니다. 예제로 직접 확인해 보겠습니다.
# Series 형태로 데이터 선택 movies_dataset["title"]
0 Avatar 1 Pirates of the Caribbean: At World's End 2 Spectre 3 The Dark Knight Rises 4 John Carter ... 4798 El Mariachi 4799 Newlyweds 4800 Signed, Sealed, Delivered 4801 Shanghai Calling 4802 My Date with Drew Name: title, Length: 4803, dtype: object
# DataFrame 형태로 데이터 선택 movies_dataset[["title"]]
| title | |
|---|---|
| 0 | Avatar |
| 1 | Pirates of the Caribbean: At World's End |
| 2 | Spectre |
| 3 | The Dark Knight Rises |
| 4 | John Carter |
| ... | ... |
| 4802 | My Date with Drew |
여러 열 선택하기
여러 열을 동시에 선택하려면 열 이름들을 리스트로 묶어 전달하면 됩니다.
# 여러 DataFrame 열 선택 movies_dataset[["title", "runtime", "vote_average", "vote_count"]]
| title | runtime | vote_average | vote_count | |
|---|---|---|---|---|
| 0 | Avatar | 162.0 | 7.2 | 11800 |
| 1 | Pirates of the Caribbean: At World's End | 169.0 | 6.9 | 4500 |
| 2 | Spectre | 148.0 | 6.3 | 4466 |
| 3 | The Dark Knight Rises | 165.0 | 7.6 | 9106 |
| 4 | John Carter | 132.0 | 6.1 | 2124 |
| ... | ... | ... | ... | ... |
| 4802 | My Date with Drew | 90.0 | 6.3 | 16 |
코드 가독성을 높이려면 열 이름들을 리스트 변수에 담아두고, 코드 안에서는 변수명을 사용하는 방식을 권장합니다.
columns = ["title", "runtime", "vote_average", "vote_count"] movies_dataset[columns]
열 이름으로 필터링: .filter() 메서드
.filter() 메서드는 문자열 기반으로 열을 검색·선택할 때 매우 유용합니다. SQL의 LIKE '%%' 조건과 거의 같은 방식으로 동작합니다. 단, 이 메서드는 실제 데이터 값이 아니라 열 이름만 검사한다는 점을 기억하세요.
.filter() 메서드는 선택 작업에 사용할 수 있는 세 가지 파라미터를 지원합니다.
likeregexitems
like 파라미터
문자열을 받아, 그 문자열이 열 이름 어디엔가 포함되어 있는 열을 찾아냅니다.
# 열 이름에 "title"이 포함된 열 선택 movies_dataset.filter(like="title").head(5)
| original_title | title | |
|---|---|---|
| 0 | Avatar | Avatar |
| 1 | Pirates of the Caribbean: At World's End | Pirates of the Caribbean: At World's End |
| 2 | Spectre | Spectre |
| 3 | The Dark Knight Rises | The Dark Knight Rises |
| 4 | John Carter | John Carter |
regex 파라미터
정규표현식(regular expression)을 사용하면 훨씬 더 유연하게 열 이름을 선택할 수 있습니다.
# 이름이 "t"로 끝나는 열 선택 movies_dataset.filter(regex="t$").head()
| budget | vote_count | |
|---|---|---|
| 0 | 237000000 | 11800 |
| 1 | 300000000 | 4500 |
| 2 | 245000000 | 4466 |
| 3 | 250000000 | 9106 |
| 4 | 260000000 | 2124 |
items 파라미터
인덱싱 연산자에 열 이름을 문자열이나 리스트로 전달하는 것과 동일하게 동작하지만, 존재하지 않는 열을 지정해도 KeyError가 발생하지 않는다는 차이가 있습니다.
데이터 유형으로 열 선택: .select_dtypes() 메서드
특정 데이터 유형의 열만 골라 사용하고 싶다면 .select_dtypes() 메서드를 활용하면 됩니다.
이 메서드는 include 또는 exclude 파라미터에 여러 데이터 유형(리스트) 또는 단일 데이터 유형(문자열)을 받으며, 지정한 유형에 해당하는 열만 담은 DataFrame을 반환합니다.
include: 지정한 데이터 유형의 열을 포함exclude: 지정한 데이터 유형의 열을 제외
먼저 데이터 유형별 열 개수부터 확인해 보겠습니다.
movies_dataset = pd.read_csv("https://raw.githubusercontent.com/sasankac/TestDataSet/master/movies_data.csv")
movies_dataset.dtypes.value_counts()object 5 int64 4 float64 3 dtype: int64
a) 정수(int) 데이터 유형만 필터링
movies_dataset.select_dtypes(include="int").head(3)
b) 정수와 실수 데이터 유형 함께 선택
여러 데이터 유형은 아래처럼 리스트로 지정할 수 있습니다.
movies_dataset.select_dtypes(include=["int64", "float"]).head(3)
| budget | id | popularity | revenue | runtime | vote_average | vote_count | |
|---|---|---|---|---|---|---|---|
| 0 | 237000000 | 19995 | 150.437577 | 2787965087 | 162.0 | 7.2 | 11800 |
| 1 | 300000000 | 285 | 139.082615 | 961000000 | 169.0 | 6.9 | 4500 |
| 2 | 245000000 | 206647 | 107.376788 | 880674609 | 148.0 | 6.3 | 4466 |
c) 모든 숫자형 데이터 유형 선택
정수든 실수든 숫자형을 모두 선택하고 싶다면 number만 지정하면 됩니다.
movies_dataset.select_dtypes(include=["number"]).head(3)
d) 특정 데이터 유형 제외하기
반대로 특정 유형을 빼고 싶다면 exclude 파라미터를 사용합니다.
movies_dataset.select_dtypes(exclude=["object"]).head(3)
참고: Pandas에는 별도의 문자열(string) 데이터 유형이 없으며, 문자열은 자동으로 Object로 처리됩니다. 따라서 실행 중 TypeError: data type "string" not understood 오류가 발생하면 string 대신 object를 사용하면 됩니다.