본 블로그는 "파이썬 머신러닝 판다스 데이터분석" 책을 기반으로 매주 스터디를 진행함을 미리 알린다
1. 데이터과학자가 판다스를 배우는 이유
Orange 프로그램을 사용해본 적이 있었는데, 코딩 없이 간단하게 연결하여 시각화가 가능하다는 장점이 있었지만, 데이터를 정제하는 과정이 생각보다 귀찮고 복잡했다. 이에 반에 판다스는 데이터를 수집하고 정리하는데 최적화된 도구라고 평가하는 사람들이 많다. 또한 비교적 간단한 언어인 파이썬을 이용하므로 많은 전문가들이 애용하는 것 같다.
2. 판다스 자료구조
판다스는 시리즈(Series), 데이터프레임(DataFrame)이라는 구조화된 데이터 형식을 제공한다. 서로 다른 종류의 무작위 데이터를 한곳에 담는 그릇이 바로 판다스이다. 다만 여기에서 시리즈는 1차원배열, 데이터프레임은 2차원 배열이라는 점에서 차이점이 존재한다.
2-1. 시리즈(Series)
인덱스 값과 데이터값이 일대일 대응이라는 구조를 가지고 있다. 각각의 인덱스는 데이터값의 위치를 나타내는 주소 역할을 한다. 파이썬의 딕셔너리와 구조가 일치하기 때문에 딕셔너리를 시리즈로 변환이 가능하다.

딕셔너리의 키(k)는 시리즈의 인덱스에 대응되고,딕셔너리의 키에 매칭되는 값(v)은 시리즈의 데이터 값으로 변환된다.
- 시리즈 민들기
#예제 1-1 딕셔너리를 시리즈로 변환
import pandas as pd
#key:value 쌍으로 딕셔너리를 만들고, 변수 dict_data에 저장
dict_data = {'a': 1, 'b': 2, 'c': 3}
#판다스 Series()함수로 dictionary를 Series로 변환, 변수 sr에 저장
sr = pd.Series(dict_data)
#sr의 자료형 출력
print(type(sr))
print(('\n'))
#변수 sr에 저장되어 있는 시리즈 객체를 출력
print(sr)
#실행결과
<class 'pandas.core.series.Series'>
a 1
b 2
c 3
dtype: int64
- 인덱스 만들기
인덱스는 자기와 짝을 이루는 데이터 값의 순서와 주소를 저장한다.

인덱스의 종류는 2가지로, 정수형 위치 인덱스(integer position), 인덱스 이름 or 인덱스 라벨이다. 즉 value 하나는 2가지 종류의 index를 가질 수 있다는 것이다.
또한 인덱 배열은 시리즈클래스를 이용하여 따로 선택이 가능하다.
Ex) sr.index(인덱스 부분만 선택), sr.values(값 부분만 선택)
- 파이썬의 list를 판다스의 series로 변환하기
파이썬의 list로 저장되어 있는 데이터를 series로 변환하게 되면 해당 값만이 변환되어 인덱스가 없는 상황이 되어버린다. 인덱스를 별도로 지정하지 않게 되면 정수 기본 위치인덱스(0,1,2,...)가 자동으로 지정된다.
#예제 1-2
import pandas as pd
#리스트를 시리즈로 변환하여 변수 sr에 저장
list_data = ['2019-01-02', '3.14', 'ABC', 100, True]
sr = pd.Series(list_data)
print(sr)
#결과값
0 2019-01-02
1 3.14
2 ABC
3 100
4 True
dtype: object
#파이썬의 리스트를 sr로 변환할때 따로 인덱스를 지정하지 않았기 때문에 0~4의 인덱스값이 나온 모습
몰랐던 사실:
- 리스트: 대괄호 [ ]로 정의되며, 순서가 있는 요소들의 시퀀스
- 사전: 중괄호 { }로 정의되며, 키-값 쌍을 저장하는 구조.
즉 중괄호{}는 maping이 필요하고 순서가 상관없는 데이터구조를 나타낼 때 사용하고,
대괄호[]는 데이터의 순서가 유지되는 곳에 사용된다.
#데이터인덱스를 따로 지정하면
#인덱스 배열은 변수 idx에 저장, 데이터 값은 변수 val에 저장
idx = sr.index
val = sr.values
print(idx)
print('\n')
print(val)
#결과값
RangeIndex(start=0, stop=5, step=1)
['2019-01-02' '3.14' 'ABC' 100 True]
- 원소 선택
인덱스를 이용하여 원소를 한 개 또는 여러 개 선택할 수 있다.
이때, 인덱스의 종류에 따라 가져오는 방식이 다른데, 인덱스 이름(위 사진 참고)은 대괄호 속에 작은따옴표를 사용하고,
정수형 위치 인덱스는 대괄호 안에 따옴표를 사용하지 않는다
import pandas as pd
#투플을 시리즈로 변환(인덱스 옵션 지정)
tup_data = ('수흠', '1999-12-11', '남', True)
sr = pd.Series(tup_data, index=['이름','생년월일','성별','학생여부'])
print(sr)
#결과값
이름 수흠
생년월일 1999-12-11
성별 남
학생여부 True
dtype: object
위처럼 인덱스 이름을 사용했으므로 [] 내부에 작은 따옴표를 사용한 모습
데이터 인덱스를 ['이름']이라고 지정했지만, 여전히 정수형 위치 인덱스 또한 사용이 가능하다
#원소를 인덱스 지졍하여 1개 선택
print(sr[0])
print(sr['이름'])
#결과값
수흠
수흠
#원소를 인덱스 지정하여 여러개 선택
print(sr[[1,2]])
print('\n')
print(sr[['생년월일','성별']])
#결과값
생년월일 1999-12-11
성별 남
dtype: object
생년월일 1999-12-11
성별 남
dtype: object
#인덱스 슬라이싱
print(sr[1:2])
print('\n')
print(sr['생년월일' : '성별'])
#인덱스 이름을 사용알 때에는 범위의 끝(성별)까지 포함되지만, 정수형의 경우는 포함 안된다
2-2 데이터프레임
2차원 배열로써 행과 열로 구성되어 있다.

시리즈를 열벡터라고 하면, 데이터프레임은 여러 개의 열벡터들이 인덱스를 기준으로 정렬된 행렬이라 보면 된다.
따라서 주소의 형태는 행 인덱스와 열 이름 or 열 라벨로 구분한다.
- 데이터 프레임 만들기
행렬이기 때문에 길이가 같은 열여러 개가 필요하다. 또한 딕셔너리 값(value)에 해당하는 각 리스트가 시리즈 배열로 변환되어 데이터프레임의 열이 된다. 딕셔너리의 키(k)는 각 시리즈의 이름으로 변환되고, 이는 데이터프레임의 열 이름이 된다.
#예제 1-4 딕셔너리-> 데이터프레임 변환
import pandas as pd
#열이름을 key, 리스트를 value로 갖는 딕셔너리 정의(행렬 배열)
dict_data = {'c0' : [1,2,3], 'c1' : [4,5,6], 'c2' : [7,8,9], 'c3' : [10,11,12], 'c4' : [13,14,15]}
#판다스 DataFrame() 함수로 딕셔너리를 데이터프레임으로 변환. 변수 df에 저장
df = pd.DataFrame(dict_data)
#df의 자료형 출력
print(type(df))
print('\n')
#변수 df에 저장되어 있는 데이터프레임 객체를 출력
print(df)
#결과값
<class 'pandas.core.frame.DataFrame'>
c0 c1 c2 c3 c4
0 1 4 7 10 13
1 2 5 8 11 14
2 3 6 9 12 15
리스트 5개를 원소로 가지는 딕셔너리를 정의하고, 그것을 DataFrame() 함수로 변환하여 3개의 원소를 가지는 5개의 열로 변환한다. 이때 딕셔너리의 키(k)가 열이름(c0~c4)이 되고, 값(v)이 열의 원소가 된다.
행은 따로 지정을 하지 않았기 때문에 자동으로 정수형 위치 인덱스(0~2)로 지정되었다.
- 행 인덱스와 열 이름의 지정
#예제 1-4
import pandas as pd
#행 인덲스/열이름 지정하여 데이터프레임 만들기
df = pd.DataFrame([[15, '남', '덕영중'], [17, '여', '수리중']],
index=['준서', '예은'],
columns=['나이', '성별', '학교']
)
#행 인덱스, 열 이름 확인하기
print(df)
print('\n')
print(df.index) #행 인덱스
print('\n')
print(df.columns) #열 이름
#결과값
나이 성별 학교
준서 15 남 덕영중
예은 17 여 수리중
Index(['준서', '예은'], dtype='object')
Index(['나이', '성별', '학교'], dtype='object')
실행 결과를 자세히 보면 list 가 열이 아닌 행으로 나열된 점을 볼 수 있다. 이전에서 했던 실습에서는 list를 원소를 갖는 딕셔너리를 이용했을 때 리스트가 열이 되었는데, 이렇게 딕셔너리를 이용하지 않았을 때에는 열이 아닌 행으로 나열된다!
- 행 인덱스와 열 이름 변경
print(df)
print("\n")
#열 이름중, '나이'를 '연령'으로, '성별' 을 '남녀'로, '학교'를 '소속' 으로 바꾸기
df.rename(columns={'나이':'연령', '성별':'남녀', '학교':'소속'}, inplace=True)
#df의 행 인덱스 중에서, '준서' 를 '학생1'로, '예은'을 '학생2'로 바꾸기
df.rename(index={'준서':'학생1', '예은':'학생2'}, inplace=True)
#df 변경후
print(df)
#결과값
나이 성별 학교
준서 15 남 덕영중
예은 17 여 수리중
연령 남녀 소속
학생1 15 남 덕영중
학생2 17 여 수리중
- drop() 메서드 : 행/열 삭제
행 삭제 시 axis= 0 또는 생략, 열 삭제시 axis=1
동시에 여러 개의 행 또는 열 삭제 시 리스트 형태로 입력한다.
행을 삭제할 때, 원래 데이터를 수정하는 것이 아닌 복제된 데이터를 수정하여 반환한다는 점에 유의한다. 따라서 원본 데이터를 수정하고 싶다면 inplace = True 옵션을 추가한다.
#예제 1-7 행 삭제하기
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {'수학': [90,80,70], '영어': [98,89,95], '음악': [85,95,100], '체육': [100,90,90]}
df= pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print('\n')
#데이터프레임 df를 복제하여 변수 df2에 저장. df2의 1개 행 삭제
df2 = df[:]
df2.drop('우현', inplace=True)
print(df2)
print('\n')
#데이터프레임 df를 복제하여 df3 저장. df3의 2개 행 삭제
df3 = df[:]
df3.drop(['우현', '인아'], axis=0, inplace=True)
print(df3)
#결과값
수학 영어 음악 체육
서준 90 98 85 100
우현 80 89 95 90
인아 70 95 100 90
수학 영어 음악 체육
서준 90 98 85 100
인아 70 95 100 90
수학 영어 음악 체육
서준 90 98 85 10
#예제 1-8 열 삭제하기
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {'수학': [90,80,70], '영어': [98,89,95], '음악': [85,95,100], '체육': [100,90,90]}
df= pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print('\n')
#데이터프레임 df를 복제하여 변수 df4에 저장. df4의 1개 열 삭제
df4 = df.copy()
df4.drop('수학', axis=1, inplace=True)
print(df4)
print('\n')
#데이터프레임 df를 복제하여 df5 저장. df5의 2개 열 삭제
df5 = df.copy()
df5.drop(['영어', '음악'], axis=1, inplace=True)
print(df5)
#결과값
수학 영어 음악 체육
서준 90 98 85 100
우현 80 89 95 90
인아 70 95 100 90
영어 음악 체육
서준 98 85 100
우현 89 95 90
인아 95 100 90
수학 체육
서준 90 100
우현 80 90
인아 70 90
- 행 선택
loc와 iloc 인덱서를 사용한다. 인덱스 이름을 기준으로 행을 선택할 경우 loc, 정수형 위치 인덱스를 사용할 때는 iloc 사용.
#예제 1-9 열 삭제하기
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {'수학': [90,80,70], '영어': [98,89,95], '음악': [85,95,100], '체육': [100,90,90]}
df= pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print('\n')
#행 인덱스를 사용하여 행 1개 선택
labell= df.loc['서준']
position1=df.iloc[0]
print(labell)
print('\n')
print(position1)
print('\n')
#행 2개선택
labell2=df.loc[['서준', '우현']]
position2=df.iloc[[0,1]]
print(labell2)
print('\n')
print(position2)
print('\n')
#행 여러개 동시선택하기 - 인덱스 슬라이싱 기법
labell3= df.loc['서준':'우현']
position3=df.iloc[0:1]
print(labell3)
print('\n')
print(position3)
#결과값
수학 영어 음악 체육
서준 90 98 85 100 #df
우현 80 89 95 90
인아 70 95 100 90
수학 90
영어 98
음악 85 #labell
체육 100
Name: 서준, dtype: int64
수학 90
영어 98 #labell2
음악 85
체육 100
Name: 서준, dtype: int64
수학 영어 음악 체육
서준 90 98 85 100 #labell3
우현 80 89 95 90
...
수학 영어 음악 체육
서준 90 98 85 100 #positio3
인덱스 이름을 범위로 지정할 경우와 정수형 위치 인덱스를 범위로 지정할 경우 다른 값이 나옴을 유의한다.
labell3와 position3 가 다른 값을 반환한다. 이는 위에서 언급한 대로 인덱스 이름과 정수형 인덱스의 범위를 지정할 때 결괏값이 다름과 원리가 같다.
- 열 선택
열을 선택할 때에는 대괄호 안에 따옴표와 같이 열 이름을 쓰거나 도트(.) 다음에 열 이름을 입력하는 2가지의 방식이 있다.
두 번째 방법은 반드시 열이름이 문자열일 경우에만 사용한다는 점에 유의한다.
#예제 1-10 열 선택하기
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {'수학': [90,80,70], '영어': [98,89,95], '음악': [85,95,100], '체육': [100,90,90]}
df= pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
print(df)
print(type(df))
print('\n')
#'수학'점수 데이터만 선택, 변수 math1에 저장
math1= df['수학']
print(math1)
print(type(math1))
print('\n')
#'영어'점수 데이터만 선택, 변수 english에 저장
english= df.영어
print(english)
print(type(english))
print('\n')
#예제 1-10 열 여러개 선택하기
#'음악', '체육'점수 데이터를 선택, 변수 music_gym에 저장
music_gym = df[['음악', '체육']]
print(music_gym)
print(type(music_gym))
print('\n')
#'수학'점수 데이터만 선택, 변수 math2에 저장 -> 대괄호 2중으로 사용시 시리즈가 아닌 데이터프레임으로 반환
math2= df[['수학']]
print(math2)
print(type(math2))
#결과값
수학 영어 음악 체육
서준 90 98 85 100
우현 80 89 95 90
인아 70 95 100 90
<class 'pandas.core.frame.DataFrame'>
서준 90
우현 80
인아 70
Name: 수학, dtype: int64
<class 'pandas.core.series.Series'>
서준 98
우현 89
인아 95
Name: 영어, dtype: int64
<class 'pandas.core.series.Series'>
음악 체육
서준 85 100
우현 95 90
인아 100 90
...
서준 90
우현 80
인아 70
<class 'pandas.core.frame.DataFrame'>
- 원소 선택하기
데이터 프레임의 [행, 열] 형식의 2차원 좌표로 원소 위치를 지정한다. 1*n 인 경우에는 시리즈 객체를, n*n 인 경우 데이터 프레임을 반환한다.
다음을 암기하자
- 인덱스 이름: DF 객체.loc[ 행 인덱스, 열 이름]
- 정수 위치 인덱스: DF 객체.iloc[ 행 번호, 열 번호]
#예제 1-11 원소 선택하기
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {
'이름': ['서준', '우현', '인아'],
'수학': [90,80,70],
'영어': [98,89,95],
'음악': [85,95,100],
'체육': [100,90,90]}
df= pd.DataFrame(exam_data, index=['서준', '우현', '인아'])
#'이름'열을 새로은 인덱스로 지정하고, df객체에 변경사항 반영
df.set_index('이름', inplace=True)
print(df)
#결과값
수학 영어 음악 체육
이름
서준 90 98 85 100
우현 80 89 95 90
인아 70 95 100 90
#'이름'열을 새로운 행 인덱스로 지정된 모습
#데이터프레임 df의 특정 원소 1개 선택('서준' 의 '음악' 점수)
a= df.loc['서준', '음악']
print(a)
b= df.iloc[0,2]
print(b)
#결과값
85
85
#데이터프레임 df의 특정 원소 2개 이상 선택('서준'의 '음악', '체육' 점수)
c= df.loc['서준', ['음악', '체육']]
print(c)
d= df.iloc[0, [2,3]]
print(d)
e= df.loc['서준', '음악':'체육']
print(e)
f= df.iloc[0,2:]
#결과값
음악 85
체육 100
Name: 서준, dtype: int64
음악 85
체육 100
Name: 서준, dtype: int64
음악 85
체육 100
Name: 서준, dtype: int64
# df 2개 이상의 행과 열에 속하는 원소를 선택('서준', '우현'의 '음악', '체육' 점수)
g= df.loc[['서준', '우현'], ['음악', '체육']]
print(g)
h= df.iloc[[0,1], [2,3]]
print(h)
i=df.loc['서준':'우현', '음악':'체육']
print(i)
j= df.iloc[0:2, 2:]
print(j)
#결과값
음악 체육
이름
서준 85 100
우현 95 90
음악 체육
이름
서준 85 100
우현 95 90
음악 체육
...
음악 체육
이름
서준 85 100
우현 95 90
이외에도 다양한 방법이 있는데, 예를 들어 df.loc[ : , ['음악', '체육']]은 모든 행에 대하여 2개의 열(음악, 체육)을 찾는다
또한 df.illoc[ : , [2,3]] 은 모든 행에 대해 인덱스 위치가 3,4번째인 열(음악, 체육)을 선택한다.
df.iloc[: , 2:4] 처럼 열 범위를 지정할 수도 있다
- 열, 행 추가
- 열 추가: df 객체['열 이름'] = 데이터 값
- 행 추가: df 객체.loc['행 이름'] = 데이터 값
#예제 1-12 열추가
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {
'이름': ['서준', '우현', '인아'],
'수학': [90,80,70],
'영어': [98,89,95],
'음악': [85,95,100],
'체육': [100,90,90]}
df= pd.DataFrame(exam_data)
print(df)
print('\n')
#데이터프레임 df에 '국어' 점수 열추가. 데이터값은 80 지정
df['국어'] = 80
print(df)
#결과값
이름 수학 영어 음악 체육
0 서준 90 98 85 100
1 우현 80 89 95 90
2 인아 70 95 100 90
이름 수학 영어 음악 체육 국어
0 서준 90 98 85 100 80
1 우현 80 89 95 90 80
2 인아 70 95 100 90 80
#예제 1-12 행 추가
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {
'이름': ['서준', '우현', '인아'],
'수학': [90,80,70],
'영어': [98,89,95],
'음악': [85,95,100],
'체육': [100,90,90]}
df= pd.DataFrame(exam_data)
print(df)
print('\n')
#데이터프레임 df에 '국어' 점수 열추가. 데이터값은 80 지정
df['국어'] = 80
print(df)
#데이터프레임 df에 '동규' 값 추가 - 같은원소값 입력
df.loc[3] = 0
print(df)
print('\n')
#데이터프렘 df에 '동규'값 추가 - 여러개 배열 지정
df.loc[4]= ['동규', 90, 80, 70, 60, 50]
print(df)
print('\n')
#새로운 행 추가- 기존 행 복사
df.loc['행5'] = df.loc[3]
print(df)
#결과값
이름 수학 영어 음악 체육
0 서준 90 98 85 100
1 우현 80 89 95 90
2 인아 70 95 100 90
이름 수학 영어 음악 체육 국어
0 서준 90 98 85 100 80
1 우현 80 89 95 90 80
2 인아 70 95 100 90 80
이름 수학 영어 음악 체육 국어
0 서준 90 98 85 100 80
1 우현 80 89 95 90 80 #새로운 행 추가, 값을 0으로 지정해서 모든 값이 0
2 인아 70 95 100 90 80
3 0 0 0 0 0 0
이름 수학 영어 음악 체육 국어
0 서준 90 98 85 100 80
1 우현 80 89 95 90 80 #새로운 행 추가(동규), 값을 따로 지정
2 인아 70 95 100 90 80
3 0 0 0 0 0 0
4 동규 90 80 70 60 50
...
2 인아 70 95 100 90 80
3 0 0 0 0 0 0
4 동규 90 80 70 60 50 #새로운 행 추가, 3행의 값을 복사
행5 0 0 0 0 0 0
- 원소 값의 변경
원소 선택에서 선택한 상태에서 = 값의 형식으로 수정이 가능하다
df.loc['서준'] ['체육'] = 90 #서준의 체육 점수를 90점으로 변경
df.iloc[0] [3] = 90
df.loc['서준', '체육'] = 90 #3개의 코드 모두 같은 값 도출
#결과값
수학 영어 음악 체육
이름
서준 90 98 85 90
우현 80 89 95 90
인아 70 95 100 90
수학 영어 음악 체육
이름
서준 90 98 85 90
우현 80 89 95 90
인아 70 95 100 90
...
이름
서준 90 98 85 90
우현 80 89 95 90
인아 70 95 100 90
마찬가지로 여러 개의 원소를 변경하기 위해서는
#여러개의 원소값 변경
df.loc['서준',['음악','체육']] = 100, 70
이런 방식을 사용한다
- 행과 열 위치 바꾸기
행열에서 열과 위치를 바꾸는 방법은 transpose 밖에 없다
#행과 열의 위치변환
df= df.transpose()
df= df.T
3. 인덱스 활용
- 특정 열을 인덱스로 설정 -df.set_index()
df.set_index('열 이름')
df.set_index('열 이름', '열 이름') #여러 열 지정
#예제 1-16 특정 열을 행 인덱스로 사용
import pandas as pd
#DataFrame ()함수로 데이터프레임 변환, 변수 df에 저장
exam_data = {
'이름': ['서준', '우현', '인아'],
'수학': [90,80,70],
'영어': [98,89,95],
'음악': [85,95,100],
'체육': [100,90,90]}
df= pd.DataFrame(exam_data)
print(df)
print('\n')
#특정 열을 데이터프레임의 행 인덱스로 설정
ndf = df.set_index(['이름'])
print(ndf)
print('\n')
ndf2= ndf.set_index('음악')
print(df2)
print('\n')
ndf3= ndf.set_index(['수학', '음악'])
print(ndf3)
#결과값
이름 수학 영어 음악 체육
0 서준 90 98 85 100
1 우현 80 89 95 90
2 인아 70 95 100 90
수학 영어 음악 체육
이름
서준 90 98 85 100 #특정 열을 행인덱스(즉 열을 행으로 변환)
우현 80 89 95 90
인아 70 95 100 90
영어 음악 체육
서준 98 85 100
인아 95 100 90
영어 체육
수학 음악
90 85 98 100
80 95 89 90
70 100 95 90
- 행 인덱스 재배열-df.reindex()
기존 데이터프레임에 존재하지 않는 행 인덱스를 추가하는 경우 내부 값이 없기 때문에 NaN(null) 값이 나온다. 이럴 경우 fill_value옵션에 원하는 값(0)을 지정하여 NaN값이 아닌 다른 값을 가지도록 한다.
#예제 1-17 새로운 배열로 행 인덱스 재지정
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]}
#딕셔너리를 데이터프레임으로 변환. 인덱스를 [r0, r1, r2]로 지정
df = pd.DataFrame(dict_data, index=['r0', 'r1', 'r2'])
print(df)
print('\n')
#인덱스를 [r0,r1,r2,r3,r4]로 재지정
new_index= ['r0', 'r1', 'r2', 'r3', 'r4']
ndf = df.reindex(new_index)
print(ndf)
print('\n')
#reindex로 발생한 NaN값을 숫자 0으로 채우기
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
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
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
- 행 인덱스 초기화-df.reset_index()
reset_index메소드를 이용하여 행 인덱스를 정수형 위치 인덱스로 초기화한다. 즉 기존의 행 인덱스는 열로 이동한다
ndf = df.reset_index()
print(ndf)
#결과값
c0 c1 c2 c3 c4
r0 1 4 7 10 13
r1 2 5 8 11 14
r2 3 6 9 12 15
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
# 행 인덱스였던 r0,r1,r2가 index열로 이동한다
- 행 인덱스를 기준으로 데이터프레임 정렬- df.sort_index()
df.sort_index(ascending = False)
- 특정 열의 데이터값을 기준으로 데이터프레임 정렬- df.sort_values()
df.sort_values(by='c1', ascending=False)
4. 산술연산
판다스 객체의 산술연산은 행/열 인덱스를 기준으로 모든 원소를 정렬하고, 동일한 위치에 있는 원소끼리 일대일 대응한다.
이때 대응되는 원소가 없다면 NaN값으로 처리한다.
4-1. 시리즈 연산
- 시리즈 vs 숫자
시리즈 객체어 어떤 숫자를 더하면 시리즈 개별 원소에 각각 더해지고, 결과가 시리즈 객체로 반환한다. 사칙연산이 모두 가능하다.
#예제 1-21
import pandas as pd
#딕셔너리 데이터로 판다스 시리즈 만들기
student1= pd.Series({'국어': 100, '영어': 80, '수학': 90})
print(student1)
print('\n')
#학생의 과목별 점수를 200으로 나누기
percentage = student1/200
print(percentage)
print('\n')
print(type(percentage))
#결과값
국어 100
영어 80
수학 90
dtype: int64
국어 0.50
영어 0.40
수학 0.45
dtype: float64
- 시리즈 vs 시리즈
시리즈와 시리즈 사이에 사칙연산을 계산한다. 벡터의 덧샘처럼 같은 성분(인덱스)을 갖는 원소끼리 사칙연산을 진행한다.
#예제 1-22 시리즈의 사칙연산
import pandas as pd
#딕셔너리로 데이터 판다스 시리즈 만들기
student1 = pd.Series({'국어': 100, '영어': 80, '수학': 90})
student2= pd.Series({'수학': 80, '국어': 90, '영어': 80})
#두 학생의 과목별 점수로 사칙연산 수행
addtion = student1 + student2 #덧샘
subtraction= student1 - student2 #뺄셈
multiplication = student1 * student2 #곱셈
division = student1 / student2 #나눗셈
#사칙연산 결과를 데이터프레임으로 합치기(시리즈 -> 데이터프레임)
result = pd.DataFrame([addtion, subtraction, multiplication, division],
index= ['덧셈', '뺄셈', '곱셈', '나눗셈'])
print(result)
#결과값
국어 수학 영어
덧셈 190.000000 170.000 160.0
뺄셈 10.000000 10.000 0.0
곱셈 9000.000000 7200.000 6400.0
나눗셈 1.111111 1.125 1.0
위와 같이 시리즈의 순서가 같지 않더라도 사칙연산 시 같은 인덱스를 가진 값끼리 연산을 진행한다. 만약 같은 인덱스를 가진 값이 없다면 NaN이 나올 것이다.
또한 이미 한쪽이 NaN값이 있다면, 해당 값을 사칙연산을 진행한다 해서 다른 값이 나오지 않는다. 즉 항상 NaN 반환된다.
이럴 때 연산 메소드에 fill_value 옵션을 사용하면 NaN 값 대신 미리 지정한 값이 반환된다.
객체명.add(더하고싶은 객체, fill_value=0)
4-2 데이터프레임 연산
데이터프레임은 여러 시리즈가 열로써 모여 하나의 행렬을 이루므로 이런 데이터프레임의 연산은 행렬의 연산과 같게 생각하면 된다. 즉 같은 행/열 인덱스에 동일하게 대응되는 같은 위치 원소끼리 연산하는 것이다.
- 데이터프레임 vs 숫자
행렬에 숫자를 더하는 것과 동일하다. 즉 모든 원소에 같은 값을 연산하는 것이다. 이때 데이터프레임은 형태를 유지한 체 원소 값만 새로운 데이터프레임을 반환한다.
add = df + 10 #df의 모든 원소에 10 더하기
- 데이터프레임 vs 데이터프레임
마찬가지로 행렬과 행렬의 연산이라고 생각한다. 따라서 같은 위치의 원소끼리 연산하고, 데이터 구조는 변하지 않는다.
new_df = df1 + df2
모든 연산에서
1. 대응되는 원소가 없을 경우
2. 대응하는 원소가 이미 NaN 값일 경우
모두 결괏값은 NaN을 도출한다. 이를 막기 위해 fill_value로 NaN일 경우 표시할 값을 지정할 수도 있다.
'파이썬 머신러닝 판다스 데이터분석' 카테고리의 다른 글
4주차- 데이터프레임의 다양한 응용 (0) | 2024.08.22 |
---|---|
3주차-데이터 사전 처리 (0) | 2024.08.21 |
3주차-시각화 도구 및 데이터 사전 처리 (0) | 2024.08.21 |
2주차- 데이터 살펴보기 (0) | 2024.08.14 |
2주차- 데이터 입출력 (0) | 2024.08.14 |