Pandas 라이브러리의 기본 객체이자 2차원 객체인 데이터프레임(DataFrame) 객체는 2차원 배열과 유사하지만, 각각 열과 행에 라벨을 붙일 수 있다. 이 라벨을 통해 인덱싱(indexing)이 가능하며, 인덱싱을 통해 원소에 접근할 수 있다. 그리고 NumPy 의 어레이 객체보다 강력하고 다양한 메서드를 지원하며 심지어 간단한 그래프도 쉽게 그릴 수 있다. 그리고 시리즈(Series) 객체를 여러개 이어붙인 것이 데이터프레임이라고 할 수 있다.
데이터프레임은 엄밀히 말하면 인덱스가 행과 열에 각각 있는데 일반적으로 데이터프레임에서 인덱스라고 하면 행(row)의 인덱스를 뜻하며 열의 인덱스는 변수명(column name)으로 지칭한다. 그리고 인덱스/변수명/값 각 요소는 .index/.columns/.values 어트리뷰트로 접근할 수 있다.
생성
데이터프레임 객체의 생성은 DataFrame() 함수에 리스트나 NumPy 어레이 객체를 입력으로 넣어 생성할 수 있으며 딕셔너리를 사용하여 생성하는 경우도 많다.
비어있는 데이터프레임 객체를 생성할 경우 함수 내부에 아무것도 쓰지 않는다.
1 2
pd.DataFrame() ## __
다음은 리스트, NumPy 어레이, 딕셔너리를 사용하여 데이터프레임 객체를 생성하는 예제이다. 시리즈와 다르게 리스트는 중첩이고 어레이는 2차원을 입력으로 하는 것을 알 수 있다.
상기 코드의 경우 “col1” 변수에 원소를 2개 입력하고 “col2” 변수에 원소를 3개 입력하였는데 그 개수가 서로 맞지 않아 에러가 발생하였다. 즉, “col1” 변수에 입력할 원소를 3개로 바꾸거나 “col2” 변수에 입력할 원소를 2개로 바꾸어 각 변수에 할당되는 객체의 원소 개수를 통일해야 올바르게 데이터프레임을 생성할 수 있다.
인덱싱
데이터프레임 객체의 인덱싱은 시리즈 객체와 같이 크게 인덱서(indexer)를 사용하는 것과 사용하지 않는 것이 있다.
데이터프레임 객체의 특정 변수의 원소에 접근하고자 할 때 어트리뷰트에 접근하는 것 처럼 마침표(.)를 사용한 코드를 작성하는 사람들이 있다. 이는 대괄호를 사용한 것 보다 입력해야하는 특수문자가 더 적기 때문에 선호하는 경향이 큰데 이는 주의해야한다. 다음의 코드를 보자.
df_t["shape"] ## 0 A ## 1 B ## Name: shape, dtype: object
“df_t” 객체의 “shape”변수의 원소를 반환하는 코드를 작성하였으나 “df_t.shape”코드의 경우 “shape”변수의 원소가 아닌 데이터프레임 객체의 “shape”어트리뷰트가 반환되는 결과를 확인할 수 있다. 이 때문에 데이터프레임 객체의 변수명이 데이터프레임 객체의 어트리뷰트명과 겹치게 된다면(충돌이 난다면) 우선순위가 변수명 보다 어트리뷰트가 높기 때문에 사용자가 원하는 결과가 나오지 않을 수 있다. 그래서 되도록이면 마침표를 사용한 데이터프레임 객체의 변수 접근 보다는 대괄호를 사용하는 것을 권장한다.
인덱서의 사용
인덱서는 시리즈와 마찬가지로 순수하게 정수만 사용가능한 .iloc[]와 다양한 입력을 받는 .loc[] 두 가지를 사용할 수 있다. 그런데 데이터프레임은 2차원 객체이기 때문에 인덱서의 대괄호 내부에 쉼표를 쓰고 쉼표 앞에 row(행)에 대한 지정이나 연산을 위한 코드를 작성하고, 쉼표 뒤에 column(열)에 대한 지정이나 연산을 위한 코드를 작성한다.
모든 열을 선택하고자 할 때는 쉼표 뒷부분을 생략하여 표현할 수 있지만, 모든 행을 선택하고자 할 때는 쉼표 앞부분을 생략할 수 없고 콜론(:)을 써야한다. 이 부분이 생소하고 불편할 수 있지만 데이터프레임 객체가 이렇게 설계되었기 때문에 어쩔 수 없이 적응하고 써야 한다.
데이터프레임 인덱싱의 경우 기본적으로 열 또는 행 하나만 선택하는 경우 그 결과가 시리즈 객체로 나오나 다음과 같이 리스트를 사용할 경우 데이터프레임으로 객체 유형이 변하지 않고 유지된다.
1
df.iloc[:, [1]]
col2
0
400
1
500
2
600
1
df.iloc[:1, [1]]
col2
0
400
1
df.iloc[:1, 1:]
col2
col3
0
400
700
1
df.iloc[:1, [0, 2]]
col1
col3
0
100
700
.loc[] 인덱서의 경우 연속범위 지정 부분에서 .iloc[]와 다르니 참고하도록 하자.