(6주차) 10월13일
해들리위컴 그래프레이어, 판다스에서 열을 선택하는 방법
-
(1/1) rpy2
-
(2/7) 데이터를 읽어오는법, 기본산점도
-
(3/7) 산점도응용 (3차원)
-
(4/7) 산점도응용 (4차원)
-
(5/7) 판다스에서 열을 선택하는 방법
-
(6/7) 판다스에서 lambda와 map을 이용하여 열을 선택하는 방법
-
(7/7) 판다스에서 lambda와 map을 이용하여 열을 선택하는 방법 (2)
import pandas as pd
from plotnine import *
import rpy2
%load_ext rpy2.ipython
%%R
### 여기는 R처럼 쓸 수 있다.
a<-c(1,2,3)
a+1
a
%%R
library(tidyverse)
mpg
mpg
%R -o mpg # R에 있던 자료가 파이썬으로 넘어옴
mpg
mpg.to_csv("mpg.csv")
pd.read_csv("mpg.csv")
# mpg = pd.read_csv("mpg.csv")
-
무언가 잘못되었다?
-
다시 저장하자.
mpg.to_csv("mpg.csv",index=False)
pd.read_csv("mpg.csv")
# mpg=pd.read_csv("mpg.csv")
- 제대로 불러졌음
pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/mpg.csv')
# mpg=pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/mpg.csv')
-
깃허브 저장소에 아예 데이터만 따로 모아서 관리하는 것도 좋은 방법입니다.
-
displ
: 자동차의 엔진크기
-
hwy
: 연료의 효율, 동일한 연료로 얼마나 멀리 가느냐?
-
자세한 설명은 R에서 ?mpg
로 알아볼것
ggplot(data = mpg) + geom_point(mapping = aes(x = "displ", y = "hwy")) ## plotnine
- 산점도: 엔진크기와 연료효율은 반비례. (엔진이 큰 차일수록 연비가 좋지 않다)
-
ggplot2를 이용한 산점도
%%R -w 800
ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy))
## 진짜 ggplot에서 그릴때에는 변수이름에 "" 를 제거함
-
객체지향적인 느낌으로 산점도 그리기
step1: 도화지를 준비한다
fig=ggplot(data=mpg)
fig
step2: 변수와 에스테틱사이의 맵핑을 설정한다.
a1=aes(x='displ',y='hwy')
a1
step3: 점들의 집합을 만든다. 즉 포인트지옴을 만든다.
point1=geom_point(mapping=a1)
- geom_point(): 점들을 그려! 어떻게?
-
a1
에서 설정된 표를 보고
step4: 도화지와 지옴을 합친다.
fig+point1
-
빠르게 그리기: mapping =
와 data=
는 생략가능함
ggplot(mpg) + geom_point(aes(x = "displ", y = "hwy")) ## plotnine
-
데이터를 다시관찰
mpg.head()
-
class도 함께 plot에 표시하면 데이터를 탐색할때 좀 더 좋을것 같다.
ggplot(data=mpg)+ geom_point(mapping=aes(x='displ',y='hwy',size= 'class'))
ggplot(data=mpg)+ geom_point(mapping=aes(x='displ',y='hwy',alpha= 'class'))
ggplot(data=mpg)+ geom_point(mapping=aes(x='displ',y='hwy',size= 'class',alpha='class'))
ggplot(data=mpg)+ geom_point(mapping=aes(x='displ',y='hwy',shape='class'))
ggplot(data=mpg)+ geom_point(mapping=aes(x='displ',y='hwy',color='class'))
-
객체지향적으로?
a2=aes(x='displ',y='hwy',color='class')
a1,a2
point2=geom_point(a2)
fig+point2
fig+point1
sline1=geom_smooth(a1)
fig+point1+sline1
fig+point2+sline1
-
명령어로 한번에 그리기
ggplot(data=mpg)+geom_point(mapping=aes(x='displ',y='hwy',color='class'))+geom_smooth(mapping=aes(x='displ',y='hwy'))
-
공통적인 맵핑규칙은 ggplot()쪽으로 빼기도 한다. (figure를 선언하는 곳에서 공통으로 선언함)
ggplot(data=mpg,mapping=aes(x='displ',y='hwy'))+geom_point(mapping=aes(color='class'))+geom_smooth()
-
R에서는 confidence interval도 geom_smooth()를 이용하여 확인할 수 있다.
%%R -w 800
ggplot(data=mpg,mapping=aes(x=displ,y=hwy))+geom_point(mapping=aes(color=class))+geom_smooth()
-
데이터를 살펴보자.
mpg.head()
-
drv (전륜, 후륜, 4륜 구동)에 따라서 데이터를 시각화 하고 싶다.
ggplot(data=mpg,mapping=aes(x='displ',y='hwy'))+geom_point(mapping=aes(size='class',color='drv'),alpha=0.2)
- 모든 $x$에 대하여 붉은색 점들이 대부분 초록선과 보라색 점들에 비하여 아래쪽에 위치하여 있음 $\to$ 4륜구동방식이 연비가 좋지 않음
-
객체지향적
a1,a2
a3=a2.copy()
id(a1),id(a2),id(a3)
a1,a2,a3
a3['color']='drv'
a3['size']='class'
a1,a2,a3
- 아래와 같이 선언해도 괜찮음
a3=aes(x='displ',y='hwy',color='drv',size='class')
point3=geom_point(a3)
fig+point3
- 앗 투명도 조절
point3=geom_point(a3,alpha=0.2)
fig+point3
-
여기에 선을 추가하여 보자.
fig+point3+sline1
-
각 그룹별로 선을 따로 그릴수도 있을까?
a1,a2,a3
a4=a2.copy()
a4['color']='drv'
sline2=geom_smooth(a4)
fig+sline2+point3
-
선의 색깔을 동일하게 하고 선의 타입을 변경하여 그룹을 표시할수도 있지 않을까?
a1,a2,a3,a4
a5=a1.copy()
a5['linetype']='drv'
a5
sline3=geom_smooth(a5,size=0.5,color='gray')
fig+point3+sline3
fig+point3+sline3+sline1
-
그래도 색깔로 구분하는것이 나은것 같다.
sline2=geom_smooth(a4,size=0.5,linetype='dashed')
fig+point3+sline2+sline1
-
고차원의 변수를 표현할 수 있는 무기는 다양하다.
- 산점도(포인트지옴): 점의크기, 점의형태, 점의색깔, 점의투명도
- 라인플랏(스무스지옴, 라인지옴): 선의형태, 선의색깔, 선의굵기
-
잘 훈련한다면 여러가지 형태의 고차원 그래프를 우리도 그릴 수 있다. (마치 미나드처럼)
-
해들리위컴은 이러한 방법을 체계적으로 정리했다고 보여진다.
-
해들리위컴: 그래프는 데이터 + 지옴 + 맵핑(변수와 에스테틱간의 맵핑) + 스탯(통계) + 포지션 + 축 + 패싯그리드 7개의 조합으로 그릴수 있다.
- 내생각: 지옴과 맵핑만 잘 이용해도 아주 다양한 그래프를 그릴 수 있음.
import numpy as np
dic={'X1':np.random.normal(0,1,5),
'X2':np.random.normal(0,1,5),
'X3':np.random.normal(0,1,5)}
df=pd.DataFrame(dic)
df
-
방법1
df.X1
-
방법2
df['X1']
-
방법3
df[['X1']]
-
df['X1']
는 series를 리턴하고df[['X1']]
는 dataframe을 리턴한다.
-
방법4
df.loc[:,'X1']
-
방법5
df.loc[:,['X1']]
-
df.loc[:,'X1']
는 series를 리턴하고df.loc[:,['X1']]
는 dataframe을 리턴한다.
-
방법6
df.loc[:,[True,False,False]]
- 불인덱싱가능
-
방법7
df.iloc[:,0]
-
방법8
df.iloc[:,[0]]
-
방법9
df.iloc[:,[True,False,False]]
import numpy as np
_df = pd.DataFrame(np.array([[1,2,3],[3,4,5],[5,6,7]]))
_df
-
아래가 모두 가능하다.
_df[0]
_df[[0]]
_df.loc[:,0]
_df.loc[:,[0]]
_df.iloc[:,0]
_df.iloc[:,[0]]
-
df.X1
로 열을 선택하는게 간단하고 편리함.
- 단점1: 변수이름을 알고 있어야 한다는 단점이 있음.
- 단점2: 변수이름에 .이 있거나 변수이름에서 공백이 있을경우 사용할 수 없음.
-
언급한 단점의 예시
dic={'X.1':np.random.normal(0,1,5),
'X.2':np.random.normal(0,1,5),
'X.3':np.random.normal(0,1,5)}
_df=pd.DataFrame(dic)
_df
_df['X.1']
df=pd.read_csv('https://raw.githubusercontent.com/PacktPublishing/Pandas-Cookbook/master/data/movie.csv')
_df.X.1
-
데이터
dic={'X1':np.random.normal(0,1,5),
'X2':np.random.normal(0,1,5),
'X3':np.random.normal(0,1,5),
'X4':np.random.normal(0,1,5)}
df=pd.DataFrame(dic)
df
-
목표: 1,2,3열을 선택
-
방법1
df[['X1','X2','X3']]
-
방법2
df.loc[:,['X1','X2','X3']]
-
방법3
df.loc[:,'X1':'X3']
-
방법4
df.loc[:,[True,True,True,False]]
-
방법5
df.iloc[:,[0,1,2]]
-
방법6
df.iloc[:,:3]
df.iloc[:,0:3]
df.iloc[:,range(3)]
-
방법7
df.iloc[:,[True,True,True,False]]
(주의) loc에서의 슬라이싱은 마지막변수를 포함하지만 iloc에서는 포함하지 않음
-
아래를 비교하라.
df.iloc[:,0:3] ## 0,1,2,3중 3은 포함되지 않는다.
df.loc[:,'X1':'X3'] ## 'X3'도 포함된다.
-
그래서 column의 이름이 integer일 경우는 종종 매우 헷갈리는 일이 일어남
_df = pd.DataFrame(np.array([[1,2,3,4],[3,4,5,6],[5,6,7,8]]))
_df
_df.loc[:,0:2]
_df.iloc[:,0:2]
df=pd.read_csv('https://raw.githubusercontent.com/PacktPublishing/Pandas-Cookbook/master/data/movie.csv')
df
-
열의 이름을 출력하여 보자.
df.columns
-
color ~ num_voted_user 를 뽑고 + aspect_ratio 도 추가적으로 뽑고싶다.
df.loc[:,['color':'num_voted_users','aspect_ratio']]
-
(팁) 복잡한 조건은 iloc으로 쓰는게 편할때가 있다. $\to$ 그런데 df.columns
변수들이 몇번인지 알아보기 힘듬 $\to$ 아래와 같이 하면 열의 이름을 인덱스와 함께 출력할 수 있음
pd.Series(df.columns)
list(range(13))+[26]
df.iloc[:,list(range(13))+[26]]
-
다시열의 이름들을 확인
df.columns
-
방법1
df.iloc[:,list(map(lambda x : 'actor' in x, df.columns) )]
-
방법2
df.loc[:,list(map(lambda x : 'actor' in x, df.columns) )]
-
방법3
df.iloc[:,map(lambda x : 'actor' in x, df.columns)]
-
방법4
df.loc[:,map(lambda x : 'actor' in x, df.columns)]
-
방법5
df.loc[:,filter(lambda x : 'actor' in x, df.columns)]
df.iloc[:,map(lambda x: 's' == x[-1],df.columns )]
df.loc[:,map(lambda x: 's' == x[-1],df.columns )]
df.iloc[:,map(lambda x: 'c' == x[0] or 'd' == x[0] ,df.columns )]
movie data frame에서 'face'라는 단어가 포함된 변수열을 선택하라.