앞 글에 이어서 메서드들에 대해 소개하겠다. 기초적인 메서드들일 수 있지만 나중에 자주 쓰일 녀석들이니 한번 공부할 때 꼼꼼히 알아두면 좋을 것 같다.
# copy 복사
- DataFrame을 복사할 때 사용한다.
1. 기존 배열을 새로운 변수에 저장한 경우
- 복사본에 변형을 주면 원본에도 변형된다.
>>> new_df=df # 새로운 변수에 저장. 복사본 생성.
>>> new_df['이름']='김사과' # '이름' 열에 '김사과' 값들이 추가됨.
>>> df.head() # 원본인 df에도 반영.
name 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수 이름
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260 김사과
1 지드래곤 빅뱅 YG 남자 1988-08-18 177.0 A 9916947 김사과
2 강다니엘 NaN 커넥트 남자 1996-12-10 180.0 A 8273745 김사과
3 뷔 방탄소년단 빅히트 남자 1995-12-30 178.0 AB 8073501 김사과
4 화사 마마무 RBW 여자 1995-07-23 162.1 A 7650928 김사과
- 이렇게 원본과 복사본의 데이터가 동시에 바뀌는 이유는 같은 메모리 주소를 참조하기 때문이다.
- 주소값 보여주는 명령어 hex()로 봐보자.
>>> hex(id(df))
'0x230b46bdbe0'
>>> hex(id(new_df))
'0x230b46bdbe0'
2. copy() 메서드를 사용한 경우
- 원본 데이터는 변하지않고, 복사본만 변형된다.
- 원본과 다른 주소를 참조하기 때문이다. 새로운 변수(공간)에 복사하는 것!
>>> copy_df = df.copy() # 새로운 변수에 복사할 때 copy()를 사용한다.
>>> hex(id(copy_df)) # 원본과 다른 주소를 참조하는 복사본.
0x230b46bddf0
>>> copy_df['이름']='반하나' # 복사본의 데이터를 바꾸면
>>> copy_df.head(3) # 복사본의 데이터는 바뀌지만
name 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수 이름
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260 반하나
1 지드래곤 빅뱅 YG 남자 1988-08-18 177.0 A 9916947 반하나
2 강다니엘 NaN 커넥트 남자 1996-12-10 180.0 A 8273745 반하나
>>> df.head(3) # 원본의 데이터는 바뀌지 않는다.
name 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수 이름
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260 김사과
1 지드래곤 빅뱅 YG 남자 1988-08-18 177.0 A 9916947 김사과
2 강다니엘 NaN 커넥트 남자 1996-12-10 180.0 A 8273745 김사과
# row, column 추가 및 삭제
1. row 추가
- 기본 데이터의 구조와 똑같이 dictionary 형태의 데이터를 만들고 append() 함수를 사용하여 데이터를 추가한다.
>>> df = pd.read_csv('http://bit.ly/ds-korean-idol') # 다시 원 데이터로 시작하자.
>>> df.append({'이름':'문윤지', '그룹':'윤지그룹','소속사':'잘 나가는 소속사', '성별':'여자', '생일':'1999-11-15', '키':'159.2', '혈액형':'O','브랜드평판지수':12345678}, ignore_index=True))
이름 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260
1 지드래곤 빅뱅 YG 남자 1988-08-18 177 A 9916947
2 강다니엘 NaN 커넥트 남자 1996-12-10 180 A 8273745
3 뷔 방탄소년단 빅히트 남자 1995-12-30 178 AB 8073501
4 화사 마마무 RBW 여자 1995-07-23 162.1 A 7650928
5 정국 방탄소년단 빅히트 남자 1997-09-01 178 A 5208335
6 민현 뉴이스트 플레디스 남자 1995-08-09 182.3 O 4989792
7 소연 아이들 큐브 여자 1998-08-26 NaN B 4668615
8 진 방탄소년단 빅히트 남자 1992-12-04 179.2 O 4570308
9 하성운 핫샷 스타크루이엔티 남자 1994-03-22 167.1 A 4036489
10 태연 소녀시대 SM 여자 1989-03-09 NaN A 3918661
11 차은우 아스트로 판타지오 남자 1997-03-30 183 B 3506027
12 백호 뉴이스트 플레디스 남자 1995-07-21 175 AB 3301654
13 JR 뉴이스트 플레디스 남자 1995-06-08 176 O 3274137
14 슈가 방탄소년단 빅히트 남자 1993-03-09 174 O 2925442
15 문윤지 윤지그룹 잘 나가는 소속사 여자 1999-11-15 159.2 O 12345678
2. column 추가
- 단순히 새로운 column을 만들고 값을 대입해주면, 그 값들로 자동 생성된다.
>>> df['국적'] = '대한민국'
>>> df.head(3)
이름 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수 국적
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260 대한민국
1 지드래곤 빅뱅 YG 남자 1988-08-18 177.0 A 9916947 대한민국
2 강다니엘 NaN 커넥트 남자 1996-12-10 180.0 A 8273745 대한민국
- 특정 행의 데이터만 바꾸기. loc 메서드를 이용한다!!
>>> df.loc[ df['이름']== '지드래곤', '국적'] = 'korea' # 모든 행에서 '이름'이 '지드래곤'인 행의 '국적'을 'korea'로 바꾼다.
>>> df.head(2)
이름 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수 국적
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260 대한민국
1 지드래곤 빅뱅 YG 남자 1988-08-18 177.0 A 9916947 korea
# 통계 정보 구하기
- 최소, 최대, 합, 평균, 분산, 표준편차 구하기
- 분산과 표준편차는 데이터가 평균으로부터 얼마나 떨어져있는지 정도를 나타낸다.
>>> df['키'].min() # 최소
162.1
>>> df['키'].max() # 최대
183.0
>>> df['키'].sum() # 합
2285.3
>>> df['키'].mean() # 평균
175.7923076923077
>>> df['키'].var() # 분산, variance
33.879102564102595
>>> df['키'].std() # 표준편차 (평균에서 퍼져있는 정도), standard deviation
5.820575793175672
- 표준편차와 분산을 numpy로 구한다면?
- 분산은 ((데이터-평균) ^2를 모두 합한값) / n 이다.
- 표준편차는 분산의 루트를 씌운 값이다.
>>> import numpy as np
>>> data_01 = np.array([1, 3, 5, 7, 9])
>>> data_01.mean() # 평균
5.0
>>> np.sqrt(((1-5)**2 + (3-5)**2 + (5-5)**2 + (7-5)**2 + (9-5)**2)/5) # numpy의 sqrt메서드로 표준편차 구하기.
2.8284271247461903
>>> data_01.var(), data_01.std() # std()값과 같은 것을 알 수 있다.
(8.0, 2.8284271247461903)
- 주로 표준편차(std)를 자주 사용하게 된다. 데이터가 평균으로부터 얼마나 퍼져있는지 정도를 나타내는 지표라고 이해하면 된다.
- count() : (null값이 아닌)개수 세는 메서드
- median() : 열에서 중앙값을 보여주는 메서드
>>> df['키'].count() # 개수
13
>>> df['키'].median() # 중앙값
177.0
- groupby() : 데이터를 그룹으로 묶어 분석할 때 활용하는 메서드
- 만약 소속사별 '키'의 평균, 성별 '키'의 평균 등 특정 그룹별 통계 및 데이터의 성질을 확인하고자 할때 활용한다.
# 소속사 별로 그룹 맺은 후, 갯수를 세는 경우
>>> df.groupby('소속사').count()
이름 그룹 성별 생년월일 키 혈액형 브랜드평판지수 국적
소속사
RBW 1 1 1 1 1 1 1 1
SM 1 1 1 1 0 1 1 1
YG 1 1 1 1 1 1 1 1
빅히트 5 5 5 5 5 5 5 5
스타크루이엔티 1 1 1 1 1 1 1 1
커넥트 1 0 1 1 1 1 1 1
큐브 1 1 1 1 0 1 1 1
판타지오 1 1 1 1 1 1 1 1
플레디스 3 3 3 3 3 3 3 3
- groupby와 함께 쓰이는 집합함수가 있다. 통계 정보를 알려주는 메서드들이다.
- count() : 갯수
- sum() : 합계
- mean() : 평균
- var() : 분산
- std() : 표준편차
- min() : 최소값
- max() : 최대값
* 단, 여러 column들 중 산술통계가 가능한 열들만 자동으로 출력하게 된다. 즉, 숫자로 되어있는 것은 다 계산한다.
# '소속사' 그룹으로 묶고, 평균을 내보자.
>>> df.groupby('소속사').mean() # Null값이 있는 행은 계산되지 않는다.
키 브랜드평판지수
소속사
RBW 162.100000 7.650928e+06
SM NaN 3.918661e+06
YG 177.000000 9.916947e+06
빅히트 176.560000 6.260169e+06
스타크루이엔티 167.100000 4.036489e+06
커넥트 180.000000 8.273745e+06
큐브 NaN 4.668615e+06
판타지오 183.000000 3.506027e+06
플레디스 177.766667 3.855194e+06
# 해당 소속사 그룹들의 특정 열에 대해서만 평균을 구하고싶다면?
>>> df.groupby('혈액형')['키'].mean()
혈액형
A 172.966667
AB 176.500000
B 183.000000
O 177.875000
Name: 키, dtype: float64
3. 데이터 전처리
# 결측값을 채워주는 fillna ()
- na값에 대하여 fill해주는 함수.
- df.info() 를 이용해서 '키'에 2개, '그룹'에 1개 데이터가 누락된 것을 확인할 수 있다.
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15 entries, 0 to 14
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 이름 15 non-null object
1 그룹 14 non-null object # 그룹에 한개 na값
2 소속사 15 non-null object
3 성별 15 non-null object
4 생년월일 15 non-null object
5 키 13 non-null float64 # 키에 두개 na값
6 혈액형 15 non-null object
7 브랜드평판지수 15 non-null int64
8 국적 15 non-null object
dtypes: float64(1), int64(1), object(7)
memory usage: 1.2+ KB
- 키가 없는 사람은 존재 할 수 없기 때문에, 데이터가 잘못되어 있는 것을 표기하기 위해 누락된 데이터를 -1로 채운다.
- inplace옵션은 기존 데이터를 수정할지말지를 정하는 옵션이다.
- 만약 inplace=True라면 또 다른 객체를 반환하지 않고 기존 객체를 수정하는 것이고,
False라면 다른 객체를 반환하여 수정하고, 기존 객체는 수정하지 않는 것이다.
- 즉 위의 명령어의 경우, 디폴트값(inplace=False)이므로 기존 객체가 수정되지 않았기 때문에 NaN값으로 채워져 있는 것을 볼 수 있다.
- 이제 inplace=True인 경우를 봐보자.
# inplace 옵션에 True를 주는 경우
>>> df['키'].fillna(-1, inplace=True) # 원본데이터까지 바뀌게 된다.
0 173.6
1 177.0
2 180.0
3 178.0
4 162.1
5 178.0
6 182.3
7 -1.0
8 179.2
9 167.1
10 -1.0
11 183.0
12 175.0
13 176.0
14 174.0
Name: 키, dtype: float64
# 다시 df['키']를 출력해봐도 여전히 빈 값에는 -1로 채워져있다. 기존데이터가 바뀐 것이다.
# 위와 같은 결과값이 출력되므로 생략하겠다.
다시 데이터를 새로 받아서 진행해보겠다.
df = pd.read_csv('http://bit.ly/ds-korean-idol')
# 데이터 타입별 column을 선택하는 select_dtypes()
# 문자열 (type=object)이 있는 column만 선택
# 그전에 각 컬럼의 타입을 확인해보자.
>>> df.info() # 키와 브랜드평판지수 컬럼을 제외하고는 모두 object이다.
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15 entries, 0 to 14
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 이름 15 non-null object
1 그룹 14 non-null object
2 소속사 15 non-null object
3 성별 15 non-null object
4 생년월일 15 non-null object
5 키 13 non-null float64
6 혈액형 15 non-null object
7 브랜드평판지수 15 non-null int64
dtypes: float64(1), int64(1), object(6)
memory usage: 1.1+ KB
>>> df.select_dtypes(include='object') # 'object'타입인 컬럼만 보여주기 (include 옵션)
이름 그룹 소속사 성별 생년월일 혈액형
0 지민 방탄소년단 빅히트 남자 1995-10-13 A
1 지드래곤 빅뱅 YG 남자 1988-08-18 A
2 강다니엘 NaN 커넥트 남자 1996-12-10 A
3 뷔 방탄소년단 빅히트 남자 1995-12-30 AB
4 화사 마마무 RBW 여자 1995-07-23 A
5 정국 방탄소년단 빅히트 남자 1997-09-01 A
6 민현 뉴이스트 플레디스 남자 1995-08-09 O
7 소연 아이들 큐브 여자 1998-08-26 B
8 진 방탄소년단 빅히트 남자 1992-12-04 O
9 하성운 핫샷 스타크루이엔티 남자 1994-03-22 A
10 태연 소녀시대 SM 여자 1989-03-09 A
11 차은우 아스트로 판타지오 남자 1997-03-30 B
12 백호 뉴이스트 플레디스 남자 1995-07-21 AB
13 JR 뉴이스트 플레디스 남자 1995-06-08 O
14 슈가 방탄소년단 빅히트 남자 1993-03-09 O
>>> df.select_dtypes(exclude='object') # object 타입을 제외한 타입만 보여주기. (exclude옵션)
키 브랜드평판지수
0 173.6 10523260
1 177.0 9916947
2 180.0 8273745
3 178.0 8073501
4 162.1 7650928
5 178.0 5208335
6 182.3 4989792
7 NaN 4668615
8 179.2 4570308
9 167.1 4036489
10 NaN 3918661
11 183.0 3506027
12 175.0 3301654
13 176.0 3274137
14 174.0 2925442
- 데이터를 학습시킬 때 문자/숫자 데이터를 훈련시키는 방법이 다르기 때문에 그 때 유용하게 쓰인다.
- 연산도 가능하다.
>>> df.select_dtypes(exclude='object') + 10
키 브랜드평판지수
0 183.6 10523270
1 187.0 9916957
2 190.0 8273755
3 188.0 8073511
4 172.1 7650938
5 188.0 5208345
6 192.3 4989802
7 NaN 4668625
8 189.2 4570318
9 177.1 4036499
10 NaN 3918671
11 193.0 3506037
12 185.0 3301664
13 186.0 3274147
14 184.0 2925452
- 변수에 저장해서 출력하는 방법을 보여주겠다.
- object 타입만 보여주는 명령어의 columns 메서드를 쓰면 해당 컬럼이름이 나온다.
>>> df.select_dtypes(exclude='object').columns
Index(['키', '브랜드평판지수'], dtype='object') # 해당 배열을 변수에 넣고 df[변수]를 하게되면 배열속 컬럼에 해당하는 값들이 나올 것이다.
>>> num_cols = df.select_dtypes(exclude='object').columns
>>> obj_cols = df.select_dtypes(include='object').columns
>>> df[num_cols]
키 브랜드평판지수
0 173.6 10523260
1 177.0 9916947
2 180.0 8273745
3 178.0 8073501
4 162.1 7650928
5 178.0 5208335
6 182.3 4989792
7 NaN 4668615
8 179.2 4570308
9 167.1 4036489
10 NaN 3918661
11 183.0 3506027
12 175.0 3301654
13 176.0 3274137
14 174.0 2925442
>>> df[obj_cols]
이름 그룹 소속사 성별 생년월일 혈액형
0 지민 방탄소년단 빅히트 남자 1995-10-13 A
1 지드래곤 빅뱅 YG 남자 1988-08-18 A
2 강다니엘 NaN 커넥트 남자 1996-12-10 A
3 뷔 방탄소년단 빅히트 남자 1995-12-30 AB
4 화사 마마무 RBW 여자 1995-07-23 A
5 정국 방탄소년단 빅히트 남자 1997-09-01 A
6 민현 뉴이스트 플레디스 남자 1995-08-09 O
7 소연 아이들 큐브 여자 1998-08-26 B
8 진 방탄소년단 빅히트 남자 1992-12-04 O
9 하성운 핫샷 스타크루이엔티 남자 1994-03-22 A
10 태연 소녀시대 SM 여자 1989-03-09 A
11 차은우 아스트로 판타지오 남자 1997-03-30 B
12 백호 뉴이스트 플레디스 남자 1995-07-21 AB
13 JR 뉴이스트 플레디스 남자 1995-06-08 O
14 슈가 방탄소년단 빅히트 남자 1993-03-09 O
# 원 핫 인코딩 (One-hot-encoding)
- 원 핫 인코딩은 한 개의 요소는 나머지 요소는 False로 만들어주는 기법이다.
- 결국 문자열 값들을 숫자형으로 인코딩하는 전처리 작업이라 생각하면 된다.
- 원-핫 인코딩이 필요한 이유?
scikit-learn에서 제공하는 머신러닝 알고리즘은 문자열 값을 입력값으로 허락하지 않기 때문에 모든 문자열 값들을 숫
자형으로 인코딩한 후에 머신러닝 모델에 학습을 시켜야한다.
- 혈액형 A,B,AB,O를 숫자 0, 1, 2, 3으로 바꾸는 예시를 해보겠다.
>>> blood_map = { # dictionary 형식으로 선언
'A' : 0,
'B' : 1,
'AB' : 2,
'O' : 3
}
>>> df['혈액형_code'] = df['혈액형'].map(blood_map)
# map 메서드로 '혈액형'의 데이터 개수(15)만큼 반복한다.
# blood_map 내에서 대칭되는 숫자로 반환되어 df['혈액형_code']에 저장.
>>> df.head(8) # '혈액형_code' 컬럼이 생긴것을 확인할 수 있다.
이름 그룹 소속사 성별 생년월일 키 혈액형 브랜드평판지수 혈액형_
code
0 지민 방탄소년단 빅히트 남자 1995-10-13 173.6 A 10523260 0
1 지드래곤 빅뱅 YG 남자 1988-08-18 177.0 A 9916947 0
2 강다니엘 NaN 커넥트 남자 1996-12-10 180.0 A 8273745 0
3 뷔 방탄소년단 빅히트 남자 1995-12-30 178.0 AB 8073501 2
4 화사 마마무 RBW 여자 1995-07-23 162.1 A 7650928 0
5 정국 방탄소년단 빅히트 남자 1997-09-01 178.0 A 5208335 0
6 민현 뉴이스트 플레디스 남자 1995-08-09 182.3 O 4989792 3
7 소연 아이들 큐브 여자 1998-08-26 NaN B 4668615 1
- map() 함수는 built-in 함수로, 딕셔너리(혹은 리스트) 안의 개별 데이터(여기선 15개)를 함수의 인자 (blood_map)로 전달하여 결과를 list로 반환해주는 함수이다.
유일한 값별 개수 세기. 이해가 안된다면 예를 들어보겠다.
A,A,A, B,B, C 데이터가 있다면, value_counts() 메서드를 이용해서, A :3개, B :2개, C :1개 로 유일한 값 별 개수를 세는 것이다.
>>> df['혈액형_code'].value_counts()
0 7
3 4
2 2
1 2
Name: 혈액형_code, dtype: int64
# A형(0) 7명, B형(1) 2명, AB형(2) 2명, O형(3) 4명인 것을 알 수 있다.
- 만약 df['혈액형_code']를 머신러닝 알고리즘에 그대로 넣어 데이터를 예측하려고 하면, 컴퓨터는 '혈액형_code'안에서 값들 간의 관계를 스스로 형성하게 된다. (머신러닝 알고리즘은 값들 간의 관계를 예측하려는 특징이 있기 때문에)
- B형은 1, AB형은 2라는 값을 가지고 있는데, 컴퓨터는 'B형+AB형=O형이다.' 라고 잘못된 관계를 맺을 수 있게 된다.
- 그렇게 하지 않기 위해서 숫자 개념을 없애야 한다. 이때 get_dummies() 메서드를 이용한다.
- 결과값으로는 각 A,B,AB,O형에 대해 true,false 값을 이용해서 표로 나타난다.
- 단지 0과 1로 이루어진 표처럼 보이지만 이는 숫자로 판단되지 않고, True&False로 여겨져 숫자와의 연관성을 없애준다.
>>> pd.get_dummies(df['혈액형_code'])
0 1 2 3
0 1 0 0 0 # A형일 때는 0을 제외한 1, 2, 3이 0이다. (0은 1, 즉 true이다.)
1 1 0 0 0
2 1 0 0 0
3 0 0 1 0
4 1 0 0 0
5 1 0 0 0
6 0 0 0 1
7 0 1 0 0
8 0 0 0 1
9 1 0 0 0
10 1 0 0 0
11 0 1 0 0
12 0 0 1 0
13 0 0 0 1
14 0 0 0 1
- prefix 옵션 : 컬럼 이름을 지정해줄 수 있다.
>>> pd.get_dummies(df['혈액형_code'], prefix='혈액형')
혈액형_0 혈액형_1 혈액형_2 혈액형_3
0 1 0 0 0
1 1 0 0 0
2 1 0 0 0
3 0 0 1 0
4 1 0 0 0
5 1 0 0 0
6 0 0 0 1
7 0 1 0 0
8 0 0 0 1
9 1 0 0 0
10 1 0 0 0
11 0 1 0 0
12 0 0 1 0
13 0 0 0 1
14 0 0 0 1
★중요한 점★
머신러닝 알고리즘으로 발전하기 위해서는 원-핫 인코딩은 꼭 알아야하는 개념이다!
또한 원-핫 인코딩 후에 get_dummies 메서드를 해줘야 숫자로 인식되지 않는다.
'Python' 카테고리의 다른 글
[colab] 5. colab으로 matplotlib를 이용한 그래프 그리기 (0) | 2021.01.22 |
---|---|
[colab] 4. colab으로 데이터 전처리 실습하기 (0) | 2021.01.22 |
[colab] 3. colab으로 pandas 모듈 사용하기(1) (0) | 2021.01.20 |
[colab] 2. colab으로 Numpy 모듈 사용하기 (0) | 2021.01.19 |
[colab] 1. 코랩 설치 및 기초 명령어 (0) | 2021.01.17 |