판다스의 자료 구조(3) - 데이터프레임(DataFrame)

업데이트:

이전글 : 판다스의 자료 구조(2) - 시리즈(Series)

데이터프레임(DataFrame)의 구조를 살펴보자

시리즈에서 데이터프레임으로

데이터프레임은 판다스에서 2차원 데이터를 다루기 위한 기본 자료형이다. 2차원의 표는 행(row)과 열(column)을 동시에 고려해야 한다. 시리즈에서 개별 자료값의 명칭 역할을 했던 인덱스(index)는 데이터프레임에서 각 ‘행’의 명칭으로 역할이 바뀐다. 2차원 표에서는 각 ‘열’의 이름도 필요한데, 데이터프레임에서는 이를 컬럼명(columns)라고 부른다. 즉, 이제는 개별 자료값마다 인덱스와 컬럼명이라는 2개의 명칭이 붙게 되는 것이다.

데이터프레임의 구성 원리는 ‘동일한 인덱스를 가진 여러 시리즈들의 결합’이다. 각각의 열을 기본 단위로 하고, 열의 이름을 구분자로 하여 이들을 결합해 만들어 낸 것이 데이터프레임이라는 것이다.

시리즈와 마찬가지로 데이터프레임도 파이썬의 딕셔너리 자료형에 기초해서 만들어졌다. 시리즈와 다른 점은, 이제 키(Key)가 컬럼명이 되고, 값(value)이 각각의 시리즈(=열)가 된다는 것이다.

지난 포스팅에서 생성한 stock 딕셔너리와 유사하게, 종목코드를 Key로, 주가를 Value로 가지는 price 딕셔너리를 아래와 같이 만들어보자.

In [1]:
price = {'A005930': 82600, 'A051910': 941000, 'A035420': 398000,
         'A005380': 242000, 'A035720': 504000, 'A068270': 318500}

stockprice를 Value로, 각각 <종목명>과 <주가>를 Key로 하는 `table` 딕셔너리를 만들어 출력해보자.

In [2]:
table = {'종목명' : stock, '주가' : price}
table
Out [2]:
{'종목명': {'A005930': '삼성전자',  'A051910': 'LG화학',  'A035420': 'NAVER',
           'A005380': '현대차',   'A035720': '카카오', 'A068270': '셀트리온'},
 '주가': {'A005930': 82600,  'A051910': 941000,  'A035420': 398000, 
         'A005380': 242000, 'A035720': 504000, 'A068270': 318500} }

‘딕셔너리 of 딕셔너리’ 형태를 가진 table 변수를 다음과 같이 pd.DataFrame 명령어의 인수로 넣으면 데이터프레임으로 변환된다.

In [3]:
df = pd.DataFrame(table)
df
Out [3]:
종목명 주가
A005930 삼성전자 82600
A051910 LG화학 941000
A035420 NAVER 398000
A005380 현대차 242000
A035720 카카오 504000
A068270 셀트리온 318500

시리즈처럼 데이터프레임도 ‘딕셔너리 of 딕셔너리’보다 훨씬 정돈된 형태로 출력이 되며, 더욱 유용한 속성과 기능들을 지니고 있다.

인덱스(index)와 컬럼명(columns)

위에 출력된 데이터프레임에서 좌측의 굵은 글씨로 된 세로줄이 인덱스, 상단의 굵은 글씨로 된 가로줄이 컬럼명이다. 데이터프레임의 인덱스는 시리즈에서와 마찬가지 .index 로 접근할 수 있다.

In [4]:
df.index
Out [4]:
Index(['A005930', 'A051910', 'A035420', 'A005380', 'A035720', 'A068270'], dtype='object')

데이터프레임의 reset_index 메서드를 사용하면 기존의 인덱스를 독립된 열로 넘기고, 새로운 정수 인덱스를 만들어낸다.

In [5]:
df1 = df.reset_index() 
df1
Out [5]:
index 종목명 주가
0 A005930 삼성전자 82600
1 A051910 LG화학 941000
2 A035420 NAVER 398000
3 A005380 현대차 242000
4 A035720 카카오 504000
5 A068270 셀트리온 318500

반대로 set_index 메서드를 사용해 특정 열의 이름을 지정하면, 해당 열이 인덱스로 바뀐다.

In [6]:
df2 = df1.set_index('종목명')
df2
Out [6]:
index 주가
종목명
삼성전자 A005930 82600
LG화학 A051910 941000
NAVER A035420 398000
현대차 A005380 242000
카카오 A035720 504000
셀트리온 A068270 318500

index 속성에 새로운 값을 직접 할당하여 수정할 수도 있다. 0부터 시작하는 정수 인덱스를 가진 df1을 1부터 시작하는 정수 인덱스를 갖도록 바꿔보자

In [7]:
df1.index = [1,2,3,4,5,6]
df1
Out [7]:
index 종목명 주가
1 A005930 삼성전자 82600
2 A051910 LG화학 941000
3 A035420 NAVER 398000
4 A005380 현대차 242000
5 A035720 카카오 504000
6 A068270 셀트리온 318500

다음으로, 데이터프레임의 컬럼명은 .columns 로 접근할 수 있다.

In [8]:
df.columns
Out [8]:
Index(['종목명', '주가'], dtype='object')

index 속성과 마찬가지로 columns 속성 역시 새로운 값을 할당해 수정할 수 있다.

In [9]:
df.columns = ['Symbol', 'Price']
df
Out [9]:
Symbol Price
A005930 삼성전자 82600
A051910 LG화학 941000
A035420 NAVER 398000
A005380 현대차 242000
A035720 카카오 504000
A068270 셀트리온 318500

지난 포스팅에서 시리즈의 Name 속성이 데이터프레임의 컬럼명과 직결된다고 언급했었다. 데이터프레임의 열이 곧 시리즈이므로, 시리즈의 Name 속성이 데이터프레임에서는 곧 열의 이름이 된다. 그리고 각 시리즈의 Name들이 모여서 columns가 되는 것이다!

리스트를 활용한 데이터프레임 생성법

앞에서는 ‘딕셔너리 of 딕셔너리’를 통해 데이터프레임을 생성했었다. 하지만 각 열마다 인덱스가 중복되기 때문에 쓸데없이 입력값이 길어지는 단점이 있다. 파이썬의 기본 자료형인 리스트(list)를 적절히 활용하면 좀 더 쉽게 데이터프레임을 생성할 수 있다.

우선 pd.DataFrame의 입력 값으로 ‘딕셔너리 of 리스트’를 사용하는 방식이다. 딕셔너리의 Key에는 각 열의 이름을, Value에는 각 열의 자료값을 리스트 형태로 넣는다. 그리고 인덱스는 별도의 리스트로 만들어 index 매개변수의 값으로 지정한다.

In [10]:
table = {'종목명' : ['삼성전자', 'LG화학', 'NAVER', '현대차', '카카오', '셀트리온'],
         '주가' : [82600, 941000, 398000, 242000, 504000, 318500]}
id = ['A005930', 'A051910', 'A035420', 'A005380', 'A035720', 'A068270']

df = pd.DataFrame(table, index=id)
df
Out [10]:
종목명 주가
A005930 삼성전자 82600
A051910 LG화학 941000
A035420 NAVER 398000
A005380 현대차 242000
A035720 카카오 504000
A068270 셀트리온 318500

‘리스트 of 리스트’를 사용하는 방법도 있다. 그런데 이 경우에는 열이 아닌 ‘행’을 기준으로 입력값을 만들어야 한다. 또한 인덱스와 컬럼명 각각을 별도의 리스트로 만들어 index / columns 매개변수의 값으로 지정한다.

In [11]:
table = [['삼성전자', 82600],
         ['LG화학', 941000],
         ['NAVER', 398000],
         ['현대차', 242000],
         ['카카오', 504000],
         ['셀트리온', 318500]]
id = ['A005930', 'A051910', 'A035420', 'A005380', 'A035720', 'A068270']
col = ['종목명','주가']

df = pd.DataFrame(table, index=id, columns=col)
df
Out [11]:
종목명 주가
A005930 삼성전자 82600
A051910 LG화학 941000
A035420 NAVER 398000
A005380 현대차 242000
A035720 카카오 504000
A068270 셀트리온 318500

물론 지금까지 실습해본 것처럼 데이터프레임이나 시리즈를 직접 생성하는 경우는 거의 드물다. 대부분 표 형식의 외부 데이터를 파이썬으로 불러와서 데이터프레임으로 변환하고, 행이나 열을 추출하여 시리즈로 변환하게 된다. 그럼에도 종종 데이터프레임이나 시리즈를 직접 생성하는 하는 경우가 생기기도 하므로 기억해두도록 하자.

각 열의 dtype 확인하기

앞서 하나의 시리즈는 구성 원소들이 취하고 있는 대표적인 자료형을 dtype 이라는 속성으로 가진다고 했다. 데이터프레임의 모든 열의 dtype을 한번에 확인하기 위해서는 dtypes 속성을 확인하면 된다.

In [12]:
df.dtypes
Out [12]:
종목명    object
주가      int64
dtype: object

참고로, 위 출력결과의 마지막 줄에 나온 dtype 은 데이터프레임 전체를 대표하는 자료형을 의미한다. 열마다 서로 다른 dtype을 가지고 있기 때문에, 데이터프레임 전체의 대표 dtype은 복합 자료형을 나타내는 object로 나오게 된다.

다음글 : 데이터를 탐색하고 골라내보자

판다스 카테고리 목록 바로가기

댓글남기기