고객 구매 데이터에서 가장 비싼 상품순으로 n개를 뽑아내려면 어떻게 할까? 고객의 구매력 평가를 위해 구매물품의 평균을 구하는 것 보다 구매한 비싼 물건을 살펴보는 것이 유용할때가 있다.
문제 상황
특정 데이터프레임의 원소의 서열이 있고 복수개가 묶여있을 때 n번째 순위의 원소만 추출하는 전처리 예제를 알아보자.
테이블이 다음과 같이 두 개 주어져 있을 때 상위 n개의 원소를 추출하여 정리해야 한다고 하자.
데이터 준비
먼저 각 타입별 순위 정보가 있는 데이터프레임을 만들어보자.
1 | df_rank = data.frame(type = LETTERS[1:5], |
다음으로 임의의 타입이 묶여있는 데이터프레임을 만들어보자.
1 | vec_c = c() |
빠른 전처리를 위해 정렬을 해준다.
1 | df_rank = df_rank[order(-df_rank$rank), ] |
Unit Test
이 코드의 핵심은 상위 n개를 사용하기 위해 정렬을 사용하지 않고 factor의 특성을 활용하여 처리하는 것이다. factor()
함수에서 보통 lebel 인자를 사용하는데 여기서는 순위를 정확하게 지정하기 위해 levels 인자를 사용하며 미리 정렬을 한 데이터를 활용하였다.
1 | vec_split = unlist(strsplit(df_c[1, 1], split = ",")) |
반복문
조금 비효율적일 수 있으나 반복문을 적용하면 다음과 같다. 이 방법은 대용량 데이터의 경우 시간이 꽤 오래걸리니 주의하도록 하자.
1 | for(n in 1:nrow(df_c)){ |
apply() 함수
앞의 반복문의 속도를 더 올리기 위해서 사용자 정의 함수와 apply()
함수를 적용하면 다음과 같다.
1 | ext_top_n = function(x, top = 2){ |
벤치마킹
상기 코드를 기반으로 100000만 row를 대상으로 벤치마크를 한 결과는 다음과 같다.
● 반복문: Time difference of 50.37027 secs
● apply()
함수: Time difference of 8.172626 secs
apply()
함수가 약 7배 정도 빠르다는 것을 알 수 있다.