Pandas에서는 문자열 데이터 타입도 지원하다 보니 이름, 제품 식별자, 코드 등으로 문자열을 분석하는 전 처리하는 경우가 많습니다. 특히, 특정 열의 문자열에서 어떤 기호나 이름을 찾는 일이 빈번한데요, 보통 stip 함수로 문자열 공백을 지우고 find 함수로 관심 있는 패턴을 찾게 됩니다. 이런 작업을 할 수 있는 방법이 여러 가지인 만큼 더 효율적인 방법 또한 존재할 텐데요, 이번 포스트에서는 특정 열의 숫자에 숫자 9가 있다면 몇 번째에 위치하는지 알고 싶어 하는 예로 살펴보겠습니다.
지난 포스트의 사용한 예제를 이용해 임의의 실수를 문자열로 변환한 열을 생성합니다. 첫 번째 소수와 소수점을 제거하고 find 함수로 9의 위치를 찾습니다. 만약 9가 없다면 -1을 반환합니다.
df['0_as_str'] = df[0].apply(lambda v: str(v))
def find_9(s):
"""Return -1 if '9' not found else its location at position >= 0"""
return s.split('.')[1].find('9')
먼저 Pandas의 str 연산을 사용해 파이썬의 문자열 메서드를 Series에 적용합니다. split은 반환 결과를 두열 (첫 번째 열에는 소수점 앞의 숫자, 두 번째 열에는 소수점 다음에 오는 숫자)로 나누고, 열 색인 중 1을 선택합니다. 이 결과에 find를 적용해 숫자 9의 위치를 찾을 수 있습니다.
>>> %timeit df['0_as_str'].str.split('.', expand=True)[1].str.find('9')
219 ms ± 10.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
- expand=True 인자를 주게 되면 split 결과로 나누어진 열을 하나의 DataFrame으로 합쳐서 리턴합니다.
- 문자열 연산 전에 Pandas Series에 대해 str 연산을 적용해야 합니다.
다음으로는 앞서 구현한 find_9 함수를 이용해 apply 메서드를 이용할 수 있습니다. 실행 시간이 앞서 에 비해 3~4배가량 짧아졌습니다. 이는 위 방법은 Pandas가 여러 중간 Series 객체를 만들어야 하지만 apply 방법을 이용하면 중간 Pandas 객체를 만들지 않고 문자열 처리가 한 번에 한 줄씩 처리됩니다. 더불어 코드도 간결해지고 find_9 함수가 맞는지 단위 테스트 또한 간결하게 작성할 수 있겠네요.
>>> %timeit df['0_as_str'].apply(find_9)
60.1 ms ± 1.69 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
'Computer > Pandas' 카테고리의 다른 글
Pandas Series, DataFrame 이어 붙이기 (0) | 2022.10.13 |
---|---|
여러 데이터 행에 함수 적용하기 (0) | 2022.10.13 |
Pandas groupby (3) (0) | 2021.08.14 |
Pandas - SettingWithCopyWarning (0) | 2021.08.11 |
Pandas groupby (2) (0) | 2021.08.07 |