판다스의 자료 구조(3) - 데이터프레임(DataFrame)
업데이트:
이전글 : 판다스의 자료 구조(2) - 시리즈(Series)
데이터프레임(DataFrame)의 구조를 살펴보자
시리즈에서 데이터프레임으로
데이터프레임은 판다스에서 2차원 데이터를 다루기 위한 기본 자료형이다. 2차원의 표는 행(row)과 열(column)을 동시에 고려해야 한다. 시리즈에서 개별 자료값의 명칭 역할을 했던 인덱스(index)는 데이터프레임에서 각 ‘행’의 명칭으로 역할이 바뀐다. 2차원 표에서는 각 ‘열’의 이름도 필요한데, 데이터프레임에서는 이를 컬럼명(columns)라고 부른다. 즉, 이제는 개별 자료값마다 인덱스와 컬럼명이라는 2개의 명칭이 붙게 되는 것이다.
데이터프레임의 구성 원리는 ‘동일한 인덱스를 가진 여러 시리즈들의 결합’이다. 각각의 열을 기본 단위로 하고, 열의 이름을 구분자로 하여 이들을 결합해 만들어 낸 것이 데이터프레임이라는 것이다.
시리즈와 마찬가지로 데이터프레임도 파이썬의 딕셔너리 자료형에 기초해서 만들어졌다. 시리즈와 다른 점은, 이제 키(Key)가 컬럼명이 되고, 값(value)이 각각의 시리즈(=열)가 된다는 것이다.
지난 포스팅에서 생성한 stock
딕셔너리와 유사하게, 종목코드를 Key로, 주가를 Value로 가지는
price
딕셔너리를 아래와 같이 만들어보자.
price = {'A005930': 82600, 'A051910': 941000, 'A035420': 398000,
'A005380': 242000, 'A035720': 504000, 'A068270': 318500}
stock
과 price
를 Value로, 각각 <종목명>과 <주가>를 Key로 하는 `table` 딕셔너리를 만들어 출력해보자.주가>종목명>
table = {'종목명' : stock, '주가' : price}
table
{'종목명': {'A005930': '삼성전자', 'A051910': 'LG화학', 'A035420': 'NAVER',
'A005380': '현대차', 'A035720': '카카오', 'A068270': '셀트리온'},
'주가': {'A005930': 82600, 'A051910': 941000, 'A035420': 398000,
'A005380': 242000, 'A035720': 504000, 'A068270': 318500} }
‘딕셔너리 of 딕셔너리’ 형태를 가진 table
변수를 다음과 같이 pd.DataFrame
명령어의 인수로 넣으면
데이터프레임으로 변환된다.
df = pd.DataFrame(table)
df
종목명 | 주가 | |
---|---|---|
A005930 | 삼성전자 | 82600 |
A051910 | LG화학 | 941000 |
A035420 | NAVER | 398000 |
A005380 | 현대차 | 242000 |
A035720 | 카카오 | 504000 |
A068270 | 셀트리온 | 318500 |
시리즈처럼 데이터프레임도 ‘딕셔너리 of 딕셔너리’보다 훨씬 정돈된 형태로 출력이 되며, 더욱 유용한 속성과 기능들을 지니고 있다.
인덱스(index)와 컬럼명(columns)
위에 출력된 데이터프레임에서 좌측의 굵은 글씨로 된 세로줄이 인덱스, 상단의 굵은 글씨로 된 가로줄이 컬럼명이다.
데이터프레임의 인덱스는 시리즈에서와 마찬가지 .index
로 접근할 수 있다.
df.index
Index(['A005930', 'A051910', 'A035420', 'A005380', 'A035720', 'A068270'], dtype='object')
데이터프레임의 reset_index
메서드를 사용하면 기존의 인덱스를 독립된 열로 넘기고, 새로운 정수 인덱스를 만들어낸다.
df1 = df.reset_index()
df1
index | 종목명 | 주가 | |
---|---|---|---|
0 | A005930 | 삼성전자 | 82600 |
1 | A051910 | LG화학 | 941000 |
2 | A035420 | NAVER | 398000 |
3 | A005380 | 현대차 | 242000 |
4 | A035720 | 카카오 | 504000 |
5 | A068270 | 셀트리온 | 318500 |
반대로 set_index
메서드를 사용해 특정 열의 이름을 지정하면, 해당 열이 인덱스로 바뀐다.
df2 = df1.set_index('종목명')
df2
index | 주가 | |
---|---|---|
종목명 | ||
삼성전자 | A005930 | 82600 |
LG화학 | A051910 | 941000 |
NAVER | A035420 | 398000 |
현대차 | A005380 | 242000 |
카카오 | A035720 | 504000 |
셀트리온 | A068270 | 318500 |
index
속성에 새로운 값을 직접 할당하여 수정할 수도 있다. 0부터 시작하는 정수 인덱스를 가진 df1
을 1부터 시작하는 정수 인덱스를
갖도록 바꿔보자
df1.index = [1,2,3,4,5,6]
df1
index | 종목명 | 주가 | |
---|---|---|---|
1 | A005930 | 삼성전자 | 82600 |
2 | A051910 | LG화학 | 941000 |
3 | A035420 | NAVER | 398000 |
4 | A005380 | 현대차 | 242000 |
5 | A035720 | 카카오 | 504000 |
6 | A068270 | 셀트리온 | 318500 |
다음으로, 데이터프레임의 컬럼명은 .columns
로 접근할 수 있다.
df.columns
Index(['종목명', '주가'], dtype='object')
index
속성과 마찬가지로 columns
속성 역시 새로운 값을 할당해 수정할 수 있다.
df.columns = ['Symbol', 'Price']
df
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
매개변수의 값으로 지정한다.
table = {'종목명' : ['삼성전자', 'LG화학', 'NAVER', '현대차', '카카오', '셀트리온'],
'주가' : [82600, 941000, 398000, 242000, 504000, 318500]}
id = ['A005930', 'A051910', 'A035420', 'A005380', 'A035720', 'A068270']
df = pd.DataFrame(table, index=id)
df
종목명 | 주가 | |
---|---|---|
A005930 | 삼성전자 | 82600 |
A051910 | LG화학 | 941000 |
A035420 | NAVER | 398000 |
A005380 | 현대차 | 242000 |
A035720 | 카카오 | 504000 |
A068270 | 셀트리온 | 318500 |
‘리스트 of 리스트’를 사용하는 방법도 있다. 그런데 이 경우에는 열이 아닌 ‘행’을 기준으로 입력값을 만들어야 한다.
또한 인덱스와 컬럼명 각각을 별도의 리스트로 만들어 index
/ columns
매개변수의 값으로 지정한다.
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
종목명 | 주가 | |
---|---|---|
A005930 | 삼성전자 | 82600 |
A051910 | LG화학 | 941000 |
A035420 | NAVER | 398000 |
A005380 | 현대차 | 242000 |
A035720 | 카카오 | 504000 |
A068270 | 셀트리온 | 318500 |
물론 지금까지 실습해본 것처럼 데이터프레임이나 시리즈를 직접 생성하는 경우는 거의 드물다. 대부분 표 형식의 외부 데이터를 파이썬으로 불러와서 데이터프레임으로 변환하고, 행이나 열을 추출하여 시리즈로 변환하게 된다. 그럼에도 종종 데이터프레임이나 시리즈를 직접 생성하는 하는 경우가 생기기도 하므로 기억해두도록 하자.
각 열의 dtype 확인하기
앞서 하나의 시리즈는 구성 원소들이 취하고 있는 대표적인 자료형을 dtype
이라는 속성으로 가진다고 했다. 데이터프레임의 모든 열의
dtype
을 한번에 확인하기 위해서는 dtypes
속성을 확인하면 된다.
df.dtypes
종목명 object
주가 int64
dtype: object
참고로, 위 출력결과의 마지막 줄에 나온 dtype
은 데이터프레임 전체를 대표하는 자료형을 의미한다. 열마다 서로 다른 dtype
을 가지고 있기 때문에, 데이터프레임 전체의 대표 dtype
은 복합 자료형을 나타내는 object로 나오게 된다.
댓글남기기