[Python] pandas 문자열 관련 함수 str

업데이트:

개요

jpg

판다스에서 문자열 관련 함수를 사용하거나 전처리를 하기 위해서는 함수 및 명령어 앞에 str을 붙여주어야 한다.

예제로는 행정표준관리시스템에서 제공하는 전국 법정동명 및 코드 데이터를 사용했다.

import pandas as pd
df = pd.read_csv(my_dir + "법정동코드", sep='\t', encoding='cp949')
df = df[df['폐지여부']=="존재"]
df.head()
법정동코드 법정동명 폐지여부
0 1100000000 서울특별시 존재
1 1111000000 서울특별시 종로구 존재
2 1111010100 서울특별시 종로구 청운동 존재
3 1111010200 서울특별시 종로구 신교동 존재
4 1111010300 서울특별시 종로구 궁정동 존재


1. 인덱싱 .str[]

# 앞 5자리까지만 추출
df['법정동명'].str[:5].head()
0    서울특별시
1    서울특별시
2    서울특별시
3    서울특별시
4    서울특별시
Name: 법정동명, dtype: object
# 마지막 한글자만 추출
df['법정동명'].str[-1].head() 
0    시
1    구
2    동
3    동
4    동
Name: 법정동명, dtype: object


2. 분할 .str.split()

# 공백(" ")으로 분리
df['법정동명'].str.split(" ").head()
0              [서울특별시]
1         [서울특별시, 종로구]
2    [서울특별시, 종로구, 청운동]
3    [서울특별시, 종로구, 신교동]
4    [서울특별시, 종로구, 궁정동]
Name: 법정동명, dtype: object

이렇게 분할된 개별 리스트를 바로 데이터 프레임으로 만드려면, expand=True옵션을 추가한다.

df['법정동명'].str.split(" ", expand=True).head()
0 1 2 3 4
0 서울특별시 None None None None
1 서울특별시 종로구 None None None
2 서울특별시 종로구 청운동 None None
3 서울특별시 종로구 신교동 None None
4 서울특별시 종로구 궁정동 None None


3. 시작글자 인식 .str.startswith()

이는 특정 boolean을 반환하는데, 특정 글자로 시작하면 True, 아니면 False 반환

df['법정동명'].str.startswith("서울").head()
0    True
1    True
2    True
3    True
4    True
Name: 법정동명, dtype: bool
# 서울로 시작하는 데이터만 필터링
df[df['법정동명'].str.startswith("서울")].head()
법정동코드 법정동명 폐지여부
0 1100000000 서울특별시 존재
1 1111000000 서울특별시 종로구 존재
2 1111010100 서울특별시 종로구 청운동 존재
3 1111010200 서울특별시 종로구 신교동 존재
4 1111010300 서울특별시 종로구 궁정동 존재


4. 끝글자 인식 .str.endswith()

# 동으로 끝나는 데이터만 필터링
df[df['법정동명'].str.endswith("동")].head()
법정동코드 법정동명 폐지여부
2 1111010100 서울특별시 종로구 청운동 존재
3 1111010200 서울특별시 종로구 신교동 존재
4 1111010300 서울특별시 종로구 궁정동 존재
5 1111010400 서울특별시 종로구 효자동 존재
6 1111010500 서울특별시 종로구 창성동 존재


5. 포함글자 인식 .str.contains()

이는 특정 boolean을 반환하는데, 특정 글자가 포함되면 True, 아니면 False 반환

# 강서구가 들어간 데이터만 필터링
df[df['법정동명'].str.contains("강서구")].head()
법정동코드 법정동명 폐지여부
737 1150000000 서울특별시 강서구 존재
740 1150010100 서울특별시 강서구 염창동 존재
741 1150010200 서울특별시 강서구 등촌동 존재
742 1150010300 서울특별시 강서구 화곡동 존재
743 1150010400 서울특별시 강서구 가양동 존재


6. 문자 위치찾기

# 왼쪽부터 검색후 위치반환 없으면 -1
df['법정동명'].str.find(' ').head()
0   -1
1    5
2    5
3    5
4    5
Name: 법정동명, dtype: int64
# 오른쪽부터 sub값 검색후 위치반환
df['법정동명'].str.rfind(sub=' ').head()
0   -1
1    5
2    9
3    9
4    9
Name: 법정동명, dtype: int64
# 찾은 모든 값 반환(정규식)
df['법정동명'].str.findall('\w+동').head()
0       []
1       []
2    [청운동]
3    [신교동]
4    [궁정동]
Name: 법정동명, dtype: object


7. 문자 대체 .str.replace()

# 공백을 "_"로 대체
df['법정동명'].str.replace(" ", "_").head()
0            서울특별시
1        서울특별시_종로구
2    서울특별시_종로구_청운동
3    서울특별시_종로구_신교동
4    서울특별시_종로구_궁정동
Name: 법정동명, dtype: object


8. 원하는 문자열 추출 str.extract()

그룹 ()을 꼭 지정해서 패턴을 입력해야 하며, 패턴에 맞는 단어가 없을 시 NaN이 출력된다.

추출그룹이 많을 땐 자동으로 데이터프레임 처리

df['법정동명'].str.extract('( \w*시 )|( \w*군 )|( \w*구 )')
            0    1      2
0         NaN  NaN    NaN
1         NaN  NaN    NaN
2         NaN  NaN   종로구 
3         NaN  NaN   종로구 
4         NaN  NaN   종로구 
5         NaN  NaN   종로구 
...
46101   서귀포시   NaN    NaN
46102   서귀포시   NaN    NaN
46103   서귀포시   NaN    NaN
46104   서귀포시   NaN    NaN
46105   서귀포시   NaN    NaN
46106   서귀포시   NaN    NaN
[20542 rows x 3 columns]
df['법정동명'].str.extract('( \w*읍)|( \w*면)|( \w*동)|(\w*\d+가)').dropna(how='all')
          0     1     2      3
2       NaN   NaN   청운동    NaN
3       NaN   NaN   신교동    NaN
4       NaN   NaN   궁정동    NaN
5       NaN   NaN   효자동    NaN
...
46102   NaN   표선면   NaN    NaN
46103   NaN   표선면   NaN    NaN
46104   NaN   표선면   NaN    NaN
46105   NaN   표선면   NaN    NaN
46106   NaN   표선면   NaN    NaN

[20283 rows x 4 columns]


9. 문자열 패딩

문자열의 길이가 고정되어 부족할 경우 채워야할 때가 있다.

# 문자열 길이 20자, 왼쪽부터 "_"로 채우기
df['법정동명'].str.pad(width=20, side='left', fillchar='_').head(10)
0    _______________서울특별시
1    ___________서울특별시 종로구
2    _______서울특별시 종로구 청운동
3    _______서울특별시 종로구 신교동
4    _______서울특별시 종로구 궁정동
5    _______서울특별시 종로구 효자동
6    _______서울특별시 종로구 창성동
7    _______서울특별시 종로구 통의동
8    _______서울특별시 종로구 적선동
9    _______서울특별시 종로구 통인동
Name: 법정동명, dtype: object
# 문자열 길이 20자, 오른쪽부터 "_"로 채우기
df['법정동명'].str.pad(width=20, side='right', fillchar='_').head(10)
0    서울특별시_______________
1    서울특별시 종로구___________
2    서울특별시 종로구 청운동_______
3    서울특별시 종로구 신교동_______
4    서울특별시 종로구 궁정동_______
5    서울특별시 종로구 효자동_______
6    서울특별시 종로구 창성동_______
7    서울특별시 종로구 통의동_______
8    서울특별시 종로구 적선동_______
9    서울특별시 종로구 통인동_______
Name: 법정동명, dtype: object
# 문자열 길이 20자, 좌우로 "_"로 채우기
df['법정동명'].str.center(width=20, fillchar='_').head(10)
0    _______서울특별시________
1    _____서울특별시 종로구______
2    ___서울특별시 종로구 청운동____
3    ___서울특별시 종로구 신교동____
4    ___서울특별시 종로구 궁정동____
5    ___서울특별시 종로구 효자동____
6    ___서울특별시 종로구 창성동____
7    ___서울특별시 종로구 통의동____
8    ___서울특별시 종로구 적선동____
9    ___서울특별시 종로구 통인동____
Name: 법정동명, dtype: object
# 왼쪽부터 0으로 채우기
df['법정동명'].str.zfill(width=20).head(10)
0    000000000000000서울특별시
1    00000000000서울특별시 종로구
2    0000000서울특별시 종로구 청운동
3    0000000서울특별시 종로구 신교동
4    0000000서울특별시 종로구 궁정동
5    0000000서울특별시 종로구 효자동
6    0000000서울특별시 종로구 창성동
7    0000000서울특별시 종로구 통의동
8    0000000서울특별시 종로구 적선동
9    0000000서울특별시 종로구 통인동
Name: 법정동명, dtype: object

추가 예제를 다른데이터를 만들어 보자.
각 데이터들은 앞뒤로 공백이 존재, 대소문자가 섞여있다.

df2 = pd.DataFrame({'col1':['abcde  ',' FFFFghij ','abCCe   '],
                    'col2':['   fgHAAij  ',' fghij ','lmnop   ']})
df2
col1 col2
0 abcde fgHAAij
1 FFFFghij fghij
2 abCCe lmnop


10. 공백제거 strip()

test1 = df2['col1'].str.strip()  # 앞 뒤 공백을 제거
test1.iloc[1]# 확인
'FFFFghij'
test2 = df2['col1'].str.lstrip()  # 앞 공백을 제거
test2.iloc[1]# 확인
'FFFFghij '
test3 = df2['col1'].str.rstrip()  # 뒤 공백을 제거
test3.iloc[1]# 확인
' FFFFghij'


11. 대소문자 변경

df2['col1'].str.lower()      # 모두 소문자로 변경
0       abcde  
1     ffffghij 
2      abcce   
Name: col1, dtype: object
df2['col1'].str.upper()      # 모두 대문자로 변경
0       ABCDE  
1     FFFFGHIJ 
2      ABCCE   
Name: col1, dtype: object
df2['col1'].str.swapcase()   # 소문자는 대문자, 대문자는 소문자로 변경 
0       ABCDE  
1     ffffGHIJ 
2      ABccE   
Name: col1, dtype: object

댓글남기기