[Python] pandas 문자열 관련 함수 str
업데이트:
개요
판다스에서 문자열 관련 함수를 사용하거나 전처리를 하기 위해서는 함수 및 명령어 앞에 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
댓글남기기