데이터 전처리/R

파이썬 split,replace,extract [R ver.]

JSMATH 2024. 6. 11. 22:18

파이썬 split,replace,extract를 먼저 소개하고 이에 같은 기능을 하는 R 함수를 소개 하겠습니다.

파이썬과 R을 동시에 공부하면 헷갈리기 때문에 확실히 하는게 중요합니다.

import numpy as np
import pandas as pd
df = pd.DataFrame({
'variable': ['왕관앵무새, 30-황조롱이, 25-뱁새, 40', '고양이, 15-부엉이, 50', '타조, 30','사랑앵무새, 8-코뉴어앵무새, 10-모란앵무새, 15']
})

#얘도 Series만 가능하네.
df.str.split('-',expand=True)
#AttributeError: 'DataFrame' object has no attribute 'str'

df2 = df['variable'].str.split('-',expand=True)
df2
	0	1	2
0	왕관앵무새, 30	황조롱이, 25	뱁새, 40
1	고양이, 15	부엉이, 50	None
2	타조, 30	None	None
3	사랑앵무새, 8	코뉴어앵무새, 10	모란앵무새, 15
#정규표현식
# " . " << 무슨 문자든 1칸은 뭐든간 ok
# " * " << * 앞 문자를 0~n번 반복
#" .* " << 무슨 문자든 앞에 나와도 상관없다.
#" .*앵무새.*$ " << $앞 문자가 끝에 있다는 말.
#즉, xxxxx앵무새xxxxx -> '또앵무야'로 변경
# 예로 왕관앵무새, 30 이면 (왕관)앵무새(, 30)  / 모든 () = xxxx라고 할 수 있음.
df2[0].str.replace('.*앵무새.*$','또앵무야',regex=True)


0       또앵무야
1    고양이, 15
2     타조, 30
3       또앵무야
Name: 0, dtype: object

다음은 str.extract()기능입니다. 특정문자를 추출하는 기능입니다.

 

#str.extarct사용
df2[0].str.extract(r'(\d)')

#앞 숫자만 가져와진다. 모두 가져올려면?
#r'(\d+)'
	0
0	3
1	1
2	3
3	8

df2[0].str.extract(r'(\d+)')

	0
0	30
1	15
2	30
3	8

 

아래는 위의 파이썬 함수와 동일 기능을 하는 R 함수입니다.

Python : str.extract ~ R : str_extract

#파이썬의 str.extract과 같은 기능 : str_extract
#library(stringr)
str_extract(df$강의시작시간,'\\d')

> str_extract(df$강의시작시간,'\\d')
[1] "1" "1" "1" "1" "1" "9"
#R에서도 동일하게 모든 수 표현하려면 \\d+
str_extract(df$강의시작시간,'\\d+시')

> str_extract(df$강의시작시간,'\\d+시')
[1] "13시" "10시" "12시" "15시" "14시" "9시"

#파이썬 str[]과 같은 기능 : substr(data,strat,stop)
start_time <- paste(str_extract(string = df$강의시작시간,pattern = '\\d+시'),ifelse(test = is.na(str_extract(string = df$강의시작시간,pattern = '\\d+분')),yes = '00분',no=str_extract(string = df$강의시작시간,pattern = '\\d+분')),sep = '')
start_time
강의시작시간<-format(strptime(start_time,format='%H시%M분'),format = '%H:%M')
강의시작시간
substr(강의시작시간,start = 1,stop = 2)

> start_time <- paste(str_extract(string = df$강의시작시간,pattern = '\\d+시'),ifelse(test = is.na(str_extract(string = df$강의시작시간,pattern = '\\d+분')),yes = '00분',no=str_extract(string = df$강의시작시간,pattern = '\\d+분')),sep = '')
> start_time
[1] "13시00분" "10시30분" "12시00분" "15시00분" "14시00분" "9시00분" 
> 강의시작시간<-format(strptime(start_time,format='%H시%M분'),format = '%H:%M')
> 강의시작시간
[1] "13:00" "10:30" "12:00" "15:00" "14:00" "09:00"

 

Python : str.contains() ~ R : grep(),str_detect()

grep(pattern = '선형',x = df$선수과목)
> grep(pattern = '선형',x = df$선수과목)
[1] 3 4 5 6

str_detect(df$강사진,'브레')
> str_detect(df$강사진,'브레')
[1] FALSE FALSE FALSE FALSE FALSE  TRUE

#위 2개 모두 df의 차원에 들어 갈 수 있는 애들임.

> df[grep(pattern = '선형',x = df$선수과목),]
                 subject                       선수과목   강사진 강의시작시간       종강일 평점 학점 수강금액 수강인원
3                 해석학            선형대수학/미적분학   츄러스         12시 24년06월30일  4.1    3   280000     32.4
4                 정수론            선형대수학/미적분학   바게트         15시 24년06월28일  3.2    2   252000     17.0
5             수리통계학            선형대수학/미적분학 애플파이         14시 24년06월30일  4.7    2   320000     15.0
6 수학을 위한 프로그래밍 선형대수학/미적분학/수리통계학   브레젤        9시30 24년06월29일  5.0    2   180000     44.0
  좌석수 개강일
3   25.0 240418
4   35.6 240419
5   22.0 240419
6   45.0 240418

> df$강사진[str_detect(df$강사진,'브레')]
[1] "브레젤"

 

Python : str.replace() ~ R : gsub()

#gsub()
variable <- c('왕관앵무새, 30-황조롱이, 25-뱁새, 40', '고양이, 15-부엉이, 50', '타조, 30','사랑앵무새, 8-코뉴어앵무새, 10-모란앵무새, 15')
gsub('고양이','냐옹',x = variable)
gsub('.*앵무새.*$','또앵무야',x = variable)


> gsub('고양이','냐옹',x = variable)
[1] "왕관앵무새, 30-황조롱이, 25-뱁새, 40"          "냐옹, 15-부엉이, 50"                          
[3] "타조, 30"                                      "사랑앵무새, 8-코뉴어앵무새, 10-모란앵무새, 15"
> gsub('.*앵무새.*$','또앵무야',x = variable)
[1] "또앵무야"              "고양이, 15-부엉이, 50" "타조, 30"              "또앵무야"

 

Python : str.split() ~ R : str_split()

> str_split(string = df$선수과목,pattern = '/')
[[1]]
[1] "없음"

[[2]]
[1] "미적분학"

[[3]]
[1] "선형대수학" "미적분학"  

[[4]]
[1] "선형대수학" "미적분학"  

[[5]]
[1] "선형대수학" "미적분학"  

[[6]]
[1] "선형대수학" "미적분학"   "수리통계학"
str_df <- str_split(string = df$선수과목,pattern = '/') %>% unlist() %>% table() %>% as.data.frame()
> str_df 
           . Freq
1   미적분학    5
2 선형대수학    4
3 수리통계학    1
4       없음    1
#시각화까지
colnames(str_df) <- c('subject','freq')

library(ggplot2)
#x = colname 'colname' 사용하지 말 것.
ggplot(str_df,aes(x=subject,y=freq))+
  geom_bar(stat = 'identity')+
  labs(title = "과목별 빈도수", x = "과목", y = "빈도수") +
  theme_minimal()

str_split으로 분리한 데이터를 빈도 수로 나타냄