[Python] 판다스(pandas) 데이터프레임(DataFrame)에서 특정 열의 문자열을 슬라이싱하기[feat. map(lambda x)]
카테고리: Python
파이썬에서 문자열을 슬라이싱(slicing)하는 것은 간단하지만, 판다스(pandas)에서 데이터프레임의 특정 열을 슬라이싱하는 것은 번거로울 수 있다. 이를테면 아래와 같은 상황이다.
result
선수 | G | 타석 | 타수 | 득점 | 안타 | 2타 | 3타 | 홈런 | 루타 | ... | 타율 | 출루율 | 장타율 | OPS | wOBA | wRC+ | WAR+ | WPA | 생년 | 포지션 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 이정후22키CF | 142 | 627 | 553 | 85 | 193 | 36 | 10 | 23 | 318 | ... | .349 | .421 | .575 | .996 | .441 | 182.5 | 9.23 | 6.72 | 1998 | CF |
1 | 피렐라22삼LF | 141 | 630 | 561 | 102 | 192 | 33 | 4 | 28 | 317 | ... | .342 | .411 | .565 | .976 | .434 | 169.3 | 7.40 | 4.20 | 1989 | LF |
2 | 나성범22KRF | 144 | 649 | 563 | 92 | 180 | 39 | 2 | 21 | 286 | ... | .320 | .402 | .508 | .910 | .411 | 157.4 | 6.50 | 3.74 | 1989 | RF |
3 | 오지환22LSS | 142 | 569 | 494 | 75 | 133 | 16 | 4 | 25 | 232 | ... | .269 | .357 | .470 | .827 | .372 | 138.6 | 5.77 | 2.56 | 1990 | SS |
4 | 최정22S3B | 121 | 505 | 414 | 80 | 110 | 21 | 0 | 26 | 209 | ... | .266 | .386 | .505 | .891 | .400 | 145.4 | 5.15 | 3.72 | 1987 | 3B |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | 고종욱22KDH | 62 | 114 | 106 | 13 | 30 | 7 | 1 | 2 | 45 | ... | .283 | .327 | .425 | .752 | .341 | 110.4 | 0.40 | 0.63 | 1989 | DH |
96 | 김기환22NCF | 73 | 131 | 113 | 26 | 25 | 5 | 1 | 0 | 32 | ... | .221 | .310 | .283 | .593 | .282 | 71.0 | 0.37 | -1.17 | 1995 | CF |
97 | 김주형22키SS | 55 | 130 | 110 | 16 | 22 | 7 | 1 | 1 | 34 | ... | .200 | .305 | .309 | .614 | .291 | 76.0 | 0.33 | -0.93 | 1996 | SS |
98 | 박상언22한C | 56 | 151 | 134 | 16 | 30 | 5 | 1 | 4 | 49 | ... | .224 | .281 | .366 | .647 | .287 | 73.4 | 0.32 | -0.83 | 1997 | C |
99 | 안승한22두C | 30 | 39 | 36 | 5 | 12 | 3 | 0 | 0 | 15 | ... | .333 | .368 | .417 | .785 | .356 | 122.1 | 0.32 | 0.21 | 1992 | C |
100 rows × 30 columns
위에 result라는 데이터프레임에서 ‘선수’라는 열은 ‘선수이름+시즌연도+팀(1글자)+포지션’으로 구성되어있다. 여기서 선수이름만 추출하여 새로운 열로 만들고 싶은 상황에 어떻게 해야 할까?
result['선수'][:3]
0 이정후22키CF
1 피렐라22삼LF
2 나성범22KRF
Name: 선수, dtype: object
위같은 코드를 작성하면 문자열이 슬라이싱되는 것이 아니라, 1~3행이 출력되어 버린다.
그래서 데이터프레임을 다루는 것이 번거롭다는 얘기다. 하지만 아래같이 작성하면 문제가 해결된다.
result['선수'].str.slice(0,3)
0 이정후
1 피렐라
2 나성범
3 오지환
4 최정2
...
95 고종욱
96 김기환
97 김주형
98 박상언
99 안승한
Name: 선수, Length: 100, dtype: object
보통 한국 사람의 이름은 3글자이니까, slice를 0부터 3의 값으로 설정했다. 그러나 이 역시 문제가 존재한다. 5행의 최정 선수 같은 외자인 이름은 제대로 슬라이싱되지 않는다. 더군다나 외국인 선수의 경우 이름이 2~5글자 등 판이할 수 있다.
그럴 때 map
과 lambda
를 적절히 사용해주면 된다. 여기선 find
함수도 쓰였는데, find
는 문자열 내에서 찾고자 하는 문자가 어느 위치(index)인지를 반환해준다.
문자열.find('찾고자 하는 문자')
즉, 아래 예시는 선수 이름 뒤에 오는 시즌년도(22)의 위치를 찾고, 그 위치전까지만 출력을 하겠다는 의미이다.
result['선수'].map(lambda x:x[:x.find('22')])
0 이정후
1 피렐라
2 나성범
3 오지환
4 최정
...
95 고종욱
96 김기환
97 김주형
98 박상언
99 안승한
Name: 선수, Length: 100, dtype: object
이를 응용하여 선수의 포지션만 출력하고 싶다면, 시즌년도에 +3을 하여 포지션이 나올 인덱스를 적절히 설정해주면 될 것이다!
result['선수'].map(lambda x:x[x.find('22')+3:])
0 CF
1 LF
2 RF
3 SS
4 3B
..
95 DH
96 CF
97 SS
98 C
99 C
Name: 선수, Length: 100, dtype: object
마지막으로, 포지션을 추출한 값을 ‘포지션’이라는 이름의 새로운 열로 생성하려면 아래처럼 작성해주면 된다!
result['포지션'] = result['선수'].map(lambda x:x[x.find('22')+3:])