티스토리 뷰

반응형

판다스란 판다스를 사용하는 목적은 서로 다른 여러 가지 유형의 데이터를 **공통의 포맷**으로 정리하는 것으로, 여러 유형의 데이터를 공통의 포맷으로 만들기 위해, **시리즈**(1차원벡터)와 **데이터프레임**(2차원벡터, 행렬)이라는 구조화된 데이터 형식을 제공한다.

 

시리즈는 여기를 눌러서 간단히 확인 후에 다시 돌아오자. 사실 아래의 내용만 코드로 입력하고 이해한다면, 판다스를 이해하는데 무리가 없을 것이다.

 

 

데이터프레임(DataFrame)

 판다스의 1차적인 목적은 서로 다른 여러 가지 유형의 데이터를 공통의 포맷으로 정리하는 것이다. 특히 행과 열로 이루어진 2차원 구조의 데이터프레임은 데이터 분석 실무에서 자주 사용된다. 2차원 배열구조는 엑셀이나 관계형 데이터베이스 등 다양한 분야에서 사용된다.

 

데이터프레임의 구조는 여러 개의 시리즈들이 모여서 구성된다. 데이터의 열은 시리즈 객체이다. 즉, 시리즈들이 모여 행렬(matrix)가 된다고 할 수 있다. 행과 열을 다양하게 불리어 진다. 헷갈리지 않도록 조심하자.

 

행 - row, 레코드(record), 관측값(observation)

열 - column, 공통의 속성을 갖는 일련의 데이터, 속성, 범주, 변수(variable)로 활용

 

쉽게 말하면 우리는 데이터정리를 위해 엑셀(Microsoft Excel)에 작성하는 것과 같이, python의 판다스로 자료정리를 하고 있다고 보면된다. 파이썬의 리스트나 딕셔너리로 된 것을 엑셀과 같이 표 형식으로 만드는 것이 **데이터프레임**으로 변환하는 것이다. (시리즈는 잘 안씀)

 

 

 

딕셔너리 변환

더보기

pandas.DataFrame(딕셔너리 객체)

 딕셔너리를 데이터프레임으로 바꿀때 시리즈와 다르기 때문에 조심해서 보자. 시리즈에서는 키값이 인덱스로 넘어갔지만, 여기서는 열이름으로 넘어가고 자동으로 행 인덱스에 숫자가 붙는다. 예시를 통해 이해해 보자.

import pandas as pd

dict_data = {'c0':[1,2,3], 'c1':[4,5,6], 'c2':[7,8,9], 'c3':[10,11,12], 'c4':[13,14,15]}
df = pd.DataFrame(dict_data)

print(type(df)) 
print()
print(df)

 위의 예를 보면 키가 열 이름이 되고, 값에 해당되는 리스트가 데이터프레임의 열이된다. 인덱스는 자동으로 생성되는 것을 알 수 있다.

 

 

 

 

리스트 변환

더보기

pandas.DataFrame(2차원 배열, index=행 인덱스 배열, columns=열 이름 배열)

바로 예시를 통해 이해하자.

import pandas as pd

df = pd.DataFrame([[18, '남','김천고'], [19, '여', '울산고']],
                 index=['진현', '민지'],
                 columns=['나이', '성별', '학교'])

print(df)
print(df.index)
print(df.columns)

 

여기서 가장 주의점은 딕셔너리는 열로 붙여졌지만, 리스트는 행으로 변환된다는 것을 인지하자.

 

# 인덱스 변경하기
df.index=['학생1', '학생2']
print(df)

 

# columns 변경하기
df.columns=['연령', '남녀', '소속']
print(df)

 

행 인댁스나 열 이름을 변경하는 다른 방법은 아래와 같다.

df.rename(columns={'나이':'연령', '성별':'남녀', '학교':'소속'}, inplace=True)
df.rename(index={'진현':'학생1', '민지':'학생2' }, inplace=True)

print(df)

이 방법은 일부를 선택하여 변경할 수 있다는 장점이 있지만, 가독서이 좋지 않아 잘 쓰지는 않는다. inplace=True 를 넣지 않으면, 원본 객체를 직접 수정하는 것이 아니라 새로운 데이터프레임 객체를 반환한다. 따라서 inplace=True를 잊지말고 넣어주자.

 

 

 

 

행/열 삭제(drop)

 데이터프레임의 행 또는 열을 삭제하는 명령으로는 drop() 메소드가 있다. 행을 삭제할 때는 axis=0을 입력하거나 아무것도 입력을 하지 않으면 된다. 열을 삭제하려면 axis=1을 입력하면 된다. 그리고 여러행/열을 삭제하려면 리스트 형태로 입력해야한다.

 

drop() 메소드는 원본 객체를 변경하지 않기 때문에 inplace=True 옵션을 추가해 줘야한다.

import pandas as pd

df = pd.DataFrame([[18, '남','김천고'], [19, '여', '울산고']],
                 index=['진현', '민지'],
                 columns=['나이', '성별', '학교'])

df.drop('진현', axis=0, inplace=True)
print(df)

 

df.drop(['나이', '학교'], axis=1, inplace=True)
print(df)

 

 

 

행 선택(loc, iloc)

 loc나 iloc나 행동하는 것은 같다. 다만, 인덱스 이름을 기준으로 행을 선택할 때는 loc를 이용하고, 정수형 위치 인덱스를 사용할 때는 iloc를 이용한다. 실습으로 이해해 보자. 기본 데이터는 아래와 같다.

import pandas as pd
exam_data = {'수학':[100, 40, 70, 30], '영어': [50, 70, 90, 80], '생물': [50, 90, 70, 18], '도덕': [88, 68, 58, 77]}
df = pd.DataFrame(exam_data, index=['진현', '민지', '성철', '지산'])

 

행선택 기초

df.loc['진현']

 

# 인덱스로 민지부분의 행 데이터를 불러왔다.
df.iloc[1]

 

만약 2개 이상의 행 인덱스를 추출하려면 리스트로 넣어서 뽑으면 된다. 물론 리스트 안에서 슬라이스 기법도 이용가능하다. 예는 아래와 같다. 다만 주의할 점은 리스트를 통채로 넣어야 한다.

df.loc['민지':]
df.loc[['진현', '지산']]
df.iloc[3:]
df.iloc[[2, 1]]

 

열선택 하기

우리가 열선택을 하는 방법은 아래와 같다. 각각을 비교할 수 있어야한다.

df.수학 df['수학'] df[['수학']]

df.수학과 df['수학']은 같은 결과값으로 시리즈 객체를 도출한다. 표현법만 다르다는 것을 인지하자. df[['수학']]로 2중 대괄호를 사용하면 시리즈가 아닌 데이터프레임을 반환한다.

만약 2개 이상의 열 인덱스를 추출하려면 리스트로 넣어서 뽑으면 된다.

df['수학', '영어']

 

 

열을 인덱스로 지정하기

딕셔너리로 들어온 열중에 그 열을 인덱스로 지정하고 싶을 때가 있다. 그때는 set_index() 메소드를 적용하여 새로운 인덱스로 지정할 수 있다. 그러면 지정된 인덱스에 덮어쓰기가 된다. 

import pandas as pd
import numpy as np
exam_data = {'수학':[100, 40, 70, 30], '영어': [50, 70, 90, 80], '생물': [50, 90, 70, 18], '도덕': [88, 68, 58, 77]}
df = pd.DataFrame(exam_data, index=['진현', '민지', '성철', '지산'])
print(df)

df.set_index('수학', inplace=True)
print(df)

----------------------------------
     수학 영어 생물 도덕
진현  100  50  50  88
민지   40  70  90  68
성철   70  90  70  58
지산   30  80  18  77
----------------------------------
    영어 생물 도덕
수학             
100  50  50  88
40   70  90  68
70   90  70  58
30   80  18  77

추가적으로 set_index('수학')과 set_index(['수학'])은 같다라는 것을 참고하자. inplace=True는 원본값을 직접 고쳐준다. index로 리스트로 담아 set_indx(['수학', '생물'])처럼 적용해도 된다. 기초 단계에서는 2개의 인덱스를 적용할 일이 많이 없다는 점을 참고하자.

 

 

 

 

원소 선택

특정 데이터를 뽑고 싶을 때가 있을 것이다.

data.loc[행, 열]
data.iloc[행, 열]
import pandas as pd
import numpy as np
exam_data = {'이름': ['진현', '민지', '성철', '지산'], '수학':[100, 40, 70, 30], '영어': [50, 70, 90, 80], '생물': [50, 90, 70, 18], '도덕': [88, 68, 58, 77]}
df = pd.DataFrame(exam_data)
print(df)

   이름 수학 영어 생물 도덕
0  진현  100  50  50  88
1  민지   40  70  90  68
2  성철   70  90  70  58
3  지산   30  80  18  77
--------------------------------
df2 = df.set_index('이름')
print(df2)

    수학 영어 생물 도덕
이름                 
진현  100  50  50  88
민지   40  70  90  68
성철   70  90  70  58
지산   30  80  18  77
--------------------------------
print(df2.iloc[1, 1:3])

영어    70
생물    90
Name: 민지, dtype: int64
-------------------------------
print(df2.loc['민지', '영어':'도덕'])

영어    70
생물    90
도덕    68
Name: 민지, dtype: int64
-------------------------------
print(df2.loc['민지', ['영어', '생물']])

영어    70
생물    90
Name: 민지, dtype: int64

추가적으로 df.iloc[1, 1]df.iloc[1][1]은 같은결과값을 출력한다.

 

 

범위 슬라이싱 응용

# 범위 슬라이싱 (기준이 행이다.)

DataFrame객체.iloc[ 시작인덱스 : 끝 인덱스 : 슬라이싱간격 ]

 

 

열/행추가

열 추가는 간단히 딕셔너리와 비슷하게 추가를 해주면 된다. 행 추가는 loc를 이용해서 추가해 준다. 이 때 값을 하나만 넣어도 전체부분이 다 채워진다. 아래의 예를 통해 참고해 보자.

### 열추가
import pandas as pd
import numpy as np
exam_data = {'이름': ['진현', '민지', '성철', '지산'], '수학':[100, 40, 70, 30], '영어': [50, 70, 90, 80], '생물': [50, 90, 70, 18], '도덕': [88, 68, 58, 77]}
df = pd.DataFrame(exam_data)
print(df)

   이름 수학 영어 생물 도덕
0  진현  100  50  50  88
1  민지   40  70  90  68
2  성철   70  90  70  58
3  지산   30  80  18  77
-------------------------
df['국어'] = 80
print(df)

  이름  수학 영어 생물 도덕 국어
0  진현  100  50  50  88  80
1  민지   40  70  90  68  80
2  성철   70  90  70  58  80
3  지산   30  80  18  77  80
--------------------------


### 행추가
df.loc[1] = ['하나', 1, 2, 3, 4, 5]
print(df)

  이름  수학 영어 생물 도덕 국어
0  진현  100  50  50  88  80
1  하나    1   2   3   4   5
2  성철   70  90  70  58  80
3  지산   30  80  18  77  80
---------------------------------
df.loc[4] = 100
print(df)

   이름  수학  영어  생물  도덕  국어
0   진현  100   50   50   88   80
1   하나    1    2    3    4    5
2   성철   70   90   70   58   80
3   지산   30   80   18   77   80
4   100   100  100  100  100  100

 

 

전치(transpose())

 데이터프레임의 행과 열을 서로 맞바꾸는 방법이다. 선형대수학의 전치행렬과 같은 개념이다. transpose() 매소드를 활용하거나 df.T와 같은 클래스 속성을 활용할 수도 있다. 두 번 실행하면 최초의 원본 데이터프레임으로 돌아온다.

import pandas as pd
import numpy as np
exam_data = {'이름': ['진현', '민지', '성철', '지산'], '수학':[100, 40, 70, 30], '영어': [50, 70, 90, 80], '생물': [50, 90, 70, 18], '도덕': [88, 68, 58, 77]}
df = pd.DataFrame(exam_data)
print(df)

  이름  수학 영어 생물 도덕
0  진현  100  50  50  88
1  민지   40  70  90  68
2  성철   70  90  70  58
3  지산   30  80  18  77
--------------------------
df = df.transpose()
print(df)

      0    1   2    3
이름  진현 민지 성철 지산
수학  100  40  70  30
영어   50  70  90  80
생물   50  90  70  18
도덕   88  68  58  77
--------------------------
df = df.T
print(df)

  이름  수학 영어 생물 도덕
0  진현  100  50  50  88
1  민지   40  70  90  68
2  성철   70  90  70  58
3  지산   30  80  18  77

 

 

 

행 인덱스 수정

 행 인덱스를 재배열하기 위해서는 reindex() 매소드와 fill_value옵션을 사용하고, 인덱스 초기화에는 reset_index() 매소드를 사용한다.

# reindex()
import pandas as pd
dict_data = {'c0':[1,2,3], 'c1':[4,5,6], 'c2':[7,8,9], 'c3':[10,11,12], 'c4':[13,14,15]}
df = pd.DataFrame(dict_data, index=['r0', 'r1', 'r2'])
print(df)

    c0  c1  c2  c3  c4
r0   1   4   7  10  13
r1   2   5   8  11  14
r2   3   6   9  12  15
-----------------------

# index를 재정의 한다. 추가되는 부분은 NaN값이 된다.
new_index = ['r0', 'r1', 'r2', 'r3', 'r4']
ndf = df.reindex(new_index)
print(ndf)

     c0   c1   c2    c3    c4
r0  1.0  4.0  7.0  10.0  13.0
r1  2.0  5.0  8.0  11.0  14.0
r2  3.0  6.0  9.0  12.0  15.0
r3  NaN  NaN  NaN   NaN   NaN
r4  NaN  NaN  NaN   NaN   NaN
------------------------------

# 추가되는 부분을 NaN이 아닌 0으로 넣으려면 fill_value옵션을 넣는다.
new_index = ['r0', 'r1', 'r2', 'r3', 'r4']
ndf2 = df.reindex(new_index, fill_value=0)
print(ndf2)

    c0  c1  c2  c3  c4
r0   1   4   7  10  13
r1   2   5   8  11  14
r2   3   6   9  12  15
r3   0   0   0   0   0
r4   0   0   0   0   0
-----------------------
# reset_index()
import pandas as pd
dict_data = {'c0':[1,2,3], 'c1':[4,5,6], 'c2':[7,8,9], 'c3':[10,11,12], 'c4':[13,14,15]}
df = pd.DataFrame(dict_data, index=['r0', 'r1', 'r2'])
print(df)

    c0  c1  c2  c3  c4
r0   1   4   7  10  13
r1   2   5   8  11  14
r2   3   6   9  12  15
-----------------------
# 기존의 index값이 행으로 빠지로 인덱스는 기본이 된다.
ndf = df.reset_index()
print(ndf)

  index  c0  c1  c2  c3  c4
0    r0   1   4   7  10  13
1    r1   2   5   8  11  14
2    r2   3   6   9  12  15

 

 

 

 

정렬

 어떤 기준에 근거해서 데이터를 정렬할 필요가 있다. Series와 DataFrame의 정렬에 대해 알아보자. 기본적으로 정렬 할 기준이 색인인지, 객체인지에 따라 사용하는 메서드가 다르다.

 

 로우나 컬럼의 색인인 경우는 sort_index 메서드를 사용한다. 디폴트 값은 오름차순이지만, 내림차순으로 정리하려면 ascending=False 옵션을 넣어준다

# Series의 색인 정렬
data = pd.Series(range(4), index=['d', 'b', 'c', 'a'])
data.sort_index()

-------------------------------------------------------
a    3
b    1
c    2
d    0
dtype: int64
# DataFrame 정렬
# axis를 활용하여 기준 축을 설정할 수 있다.
frame = pd.DataFrame(np.arange(8).reshape(2, 4), 
                    index=['three', 'one'],
                    columns=['d', 'a', 'b', 'c'])

print(frame)
print(frame.sort_index())
print(frame.sort_index(axis=1))

------------------
       d  a  b  c
three  0  1  2  3
one    4  5  6  7
------------------
       d  a  b  c
one    4  5  6  7
three  0  1  2  3
------------------
       a  b  c  d
three  1  2  3  0
one    5  6  7  4

 

 

객체의 에 따라 정렬을 하려면 sort_values 메서드를 사용한다. 이 때 Series 객체에서 비어있는 값은 기본적으로 마지막에 위치한다.

# Series의 객체 값에 따른 정렬
# NaN은 가장 마지막에 위치한다
data = pd.Series([4, 9, np.nan, 3, -1, np.nan])
print(data)
print(data.sort_values())
-----------------------------
0    4.0
1    9.0
2    NaN
3    3.0
4   -1.0
5    NaN
dtype: float64
------------------------------
4   -1.0
3    3.0
0    4.0
1    9.0
2    NaN
5    NaN
dtype: float64
frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 1, 0]})
print(frame)
# b 컬럼 으로 정렬하기
print(frame.sort_values(by='b'))
# 여러 개의 컬럼 으로 정렬하기
# 리스트의 왼쪽인 'a'를 정렬한 후에 'b'를 정렬한다. 
print(frame.sort_values(by=['a', 'b']))
----------------------------------------
   b  a
0  4  0
1  7  1
2 -3  1
3  2  0
-----------------------------------------
   b  a
2 -3  1
3  2  0
0  4  0
1  7  1
-----------------------------------------
   b  a
3  2  0
0  4  0
2 -3  1
1  7  1
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함