본문 바로가기
데이터과학 기초/Python배우기

파이썬으로 빠르게 글자 수 세기 - Counter

by eigenvector 2022. 8. 17.
반응형

파이썬은 데이터 사이언스 도구로 알려져 있지만, 단순한 반복 작업을 대체하기 위해 파이썬을 사용하는 사람도 많습니다.

 

오늘은 이런 단순 작업 중, Counter로 대표되는 글자 수 세는 방법을 방법을 살펴보겠습니다.

 

Counter는 이름대로 숫자를 세는 함수로, 워드 클라우드 같은 빈도 기반의 작업과 연계되는 중요한 역할을 합니다.

 

입력/출력 과정이 복잡한 측면이 있어 처음에 익숙해 지기는 어렵지만, 한번 효용을 알게 되면 데이터 분석에서 무조건 한번 이상 사용하게 되는 명령어이기도 합니다.

 

(특히, NLP와 같은 문자 처리에서는 Counter 명령어의 다양한 사용법을 아는 것이 필수입니다)

 

오늘은 간략한 Counter의 사용 방법과 예시를 확인해 보도록 하겠습니다.

 


colletions과 Counter

Counter는 구체적으로, collections 패키지에 속한 명령어입니다.

 

collections는 파이썬에 기초적으로 내장된 유용한 기능을 묶어놓은 패키지로 defaultdict과 같이 딕셔너리와 연결된 명령어를 제공합니다.

 

collections의 경우, 기본적으로 내장된 패키지이기 때문에 추가로 conda나 pip을 사용할 필요 없이 아래와 같이 작업을 진행해 주시면 됩니다.

 


샘플 텍스트 로드

 

우선, 테스트를 하기 위해 적당한 단어 목록 텍스트를 하나 만들어 왔습니다.

 

텍스트는 과일(사과, 배, 딸기, 키위, 바나나, 포도, 오렌지, 귤, 파인애플, 멜론, 복숭아, 망고스틴....)이름을 적어놓은 내용입니다.

 

아래 fruits.txt 파일을 다운로드하여 주세요.

 

fruits.txt
0.02MB

 

다운로드한 텍스트 파일을 파이썬 폴더 내로 옮겨주세요.

 

이제, 작업을 시작해 보도록 하겠습니다.

 

저는 Jupyter Notebook 환경에서 작업했지만, 취향에 맞는 환경을 설정해 주시면 되겠습니다.

 


테스트 파일 읽기

 

이제 텍스트 파일을 읽어보도록 하겠습니다.

 

텍스트 파일을 open으로 열고, read로 내용을 text항목으로 전달해 주는 명령을 수행합니다.

 

text = open("./fruits.txt").read()

 

텍스트 파일이 제대로 text에 읽혔는지 확인해 볼까요?

 

 

텍스트 파일이 문자 형태(string)로 잘 로드되어 text에 할당된 것이 확인됩니다.

 

이제, 빈도수를 세기 위해 Counter를 구체적으로 사용해 봅시다.

 


Counter 함수 불러오기

 

앞선 설명에서 제시한 바처럼, collections 패키지에 포함된 Counter는 추가적인 설치 없이 사용이 가능합니다(로드 시 대문자에 주의 해 주세요).

 

from collections import Counter

 

이제 Counter 함수에 값을 넣어야 하는데, 어떻게 넣어주면 될까요?

 

Counter함수에 문자열을 그대로 넣으면, 안타깝게도 글자 하나의 수를 세서 반환해 줍니다.

 

 

그렇다면, 우리가 원하는 대로 공백을 분리해서 글자 수를 세려면 어떻게 해야 할까요?

 

답은 "리스트로 변환해서 넣어준다"입니다.

 


Counter의 단짝 split

Counter에서 문자를 세는 기준은 크게 두 가지입니다.

 

  • 그대로 글자 하나하나를 센다(문자열을 넣어줬을 때)
  • 리스트 안에 있는 문자(단어)의 빈도를 센다(리스트를 넣어 줬을 때)

 

일반적으로 후자의 케이스가 많기 때문에, 우리는 "문자열을 리스트로 변환"할 수 있는 방법을 생각해야 합니다.

 

이때, 사용 가능한 것이 split 명령어입니다. Split 명령어는 문자열을 우리가 생각한 단위로 잘라 리스트로 변환해 줍니다.

 

시험 삼아 " "(공백)을 기준으로 문자열을 split로 나눠 볼까요?

 

split은 문자 객체에 그대로 dot(.)을 찍고 사용하면 됩니다. 구체적으로, split 함수에 공백을 나눌 내용을 넣으면 그대로 리스트를 반환합니다.

 

text.split(" ")

 

위 명령어를 수행하면 text에 있는 문자열을 " "(공백) 단위로 나눠서 리스트로 만들어 주는 것이지요. 결과를 확인해 볼까요?

 

list로 변환된 것이 맞는지 유형을 구체화해서 확인해 봅시다.

 

문자열이 리스트 객체로 변환된 것이 확인됩니다.

 

* 참고로 일반적인 공백의 경우 split(" ") 대신, 그냥 split()을 사용하더라도 동일한 결과가 나옵니다. (아마도) 너무 많이 사용하는 명령어이기 때문이라고 생각합니다.

 

 

이제, list형태를 다시 Counter 함수에 넣어봅시다.

 


Counter 결과 편리하게 정리하기 - Most Common

Counter 함수에 앞에서 설명한 split으로 변환한 리스트를 넣어줄 경우, 단어 수를 제대로 셀 수 있습니다.

 

(굳이 공백을 추가하지 않고, split()을 사용한 이유는 앞에서 설명했습니다)

 

Counter(text.split())

다만, 이렇게 Counter 함수를 사용하면 문제가 발생합니다. 해석이 어렵기 때문입니다.

 

구체적으로 문제는 다음과 같이 정리됩니다.

 

  • 객체가 Counter 속성을 갖고 있기 때문에 활용하기 복잡하고
  • 빈도가 정리가 되지 않았기 때문에 한눈에 파악하기 어렵다

즉, 구체적으로 Counter 함수 결과를 꺼내 쓰려면 아래와 같이 복잡한 문제를 보게 됩니다.

 

그렇기 때문에, Counter 명령어를 사용한 이후 이를 해석하기 위해 items나 여러 방법을 사용합니다.

 

그중, 경험상 제가 가장 추천하는 방식은 most_common을 사용하는 방식입니다.

 

most_common 명령어를 쓰게 되면 다음과 같은 일이 일어납니다.

 

  • Counter 객체가 list 객체로 변경되면서 편집이 간편해진다.
  • 빈도가 가장 높은 순서로 정렬돼서 확인하기가 편해진다.

실제로 most_common 명령어를 사용해 볼까요? most_common은 Counter 객체에 그대로 dot(.)을 찍고 사용하면 됩니다.

 

Counter(text.split()).most_common()

좀 더 응용해서 () 안에 원하는 상위 순위를 적어, 상위 내용만 추출하는 것도 가능합니다.

 

Counter(text.split()).most_common(3)

 


리스트 슬라이싱과 most_common 결합하기

그렇다면, list 형태의 결과를 어떻게 쉽게 다룰까요?

 

list 객체를 다루는 것은 경험의 영역이기에 본인이 많이 쓰는 명령어를 외워놓으면 편리합니다.

 

저 같은 경우 다음과 같이 상위 n개, 하위 n개를 추출하는 명령어를 많이 사용합니다.

 

Counter(text.split()).most_common()[:3]

Counter(text.split()).most_common()[-3:]

 

 

list 형태기 때문에, 다음과 같이 쉽게 for~in으로 꺼낼 수도 있습니다. 이때, 각각의 파라미터를 할당해서 필터링을 걸면 편리하게 추출이 가능합니다.

 

for word, count in Counter(text.split()).most_common():
    if count > 100:
        print(word, count)

 

추가적인 Counter의 명령어가 존재하지만, 이 정도로도 충분히 활용이 가능하다고 생각합니다.

 

(바로바로 기억해내서 쓰는 것이 중요하기 때문입니다)

 


정리

  • 파이썬에서는 collections라는 기본 패키지가 존재하고 Counter가 포함되어 있다
  • 파이썬에서 글자 수 세기는 Counter로 가능하다
  • Counter에는 문자열도 가능하지만, list 형태를 넣어서 빈도를 세는 것이 편하다
  • Most_Common 명령어로 쉽게 빈도수 결과를 편집할 수 있다.
반응형