이번 포스팅에서는 Pandas Series 의 value 를 전처리할 수 있는 여러가지 메소드를 정리해 보려고 합니다. 이 포스팅은 https://www.geeksforgeeks.org/ 사이트를 참고 하였으며 예제도 사이트의 예제를 그대로 가져왔습니다.
예제로 사용할 데이터 입니다. NBA 의 선수들의 정보를 담고 있는 데이터 입니다. 9개의 칼럼 457개의 행 이며, 하기 데이터 프레임을 data 라는 개체에 할당하겠습니다.
Pandas Series 의 경우 개별 원소 모두에 대해 일괄로 전처리 작업이 필요할 경우 .str 를 함께 사용합니다. Series.str. 를 이용한 대표적인 메서드를 정리해 보겠습니다.
1. Series.str.strip()
문자열에 공백이 있을 때, 공백을 제거하기 위해선 strip() 을 사용합니다.
- Series.str.lstrip() : 문자열의 왼쪽 공백 제거
- Series.str.rstrip() : 문자열의 오른쪽 공백 제거
- Series.str.strip() : 문자열의 양쪽 공백 제거
2. Series.str.slice()
.str.slice() 를 사용하면 판다스의 슬라이싱처럼 시리즈의 각 value 에 대해 일부를 슬라이싱(일부 추출) 할 수 있습니다. 하기와 같이 사용할 수 있습니다.
- Series.str.slice(시작위치: 끝 위치: 간격)
위의 Salary 열의 데이터를 살펴보면 소수점 한 자리로 이루어져 있습니다. 이를 정수(int) 로 변환하고 싶습니다. 이를 Series.str.slice 를 사용하여 어떻게 변환하는지 하기를 통해 살펴봅시다.
- 우선 Series.str 메소드는 string 에서만 적용될 수 있으므로 astype 을 이용하여 string 으로 데이터 변환을 합니다.
- 그 후 str.slice 를 통해 소수점 앞만 추출합니다. 이 때 맨 처음부터 시작하므로 0, 소수점 앞자리가 마지막이므로 -2, 모두 추출하므로 간격은 1을 설정합니다. Series.str.slice(0, -2, 1)
- 새로 추출한 데이터는 Salary (Int) 열에 할당합니다.
# series.slice
# start, stop, step variables
start, stop, step = 0, -2, 1
# to convert to string for slicing
data['Salary'] = data['Salary'].astype(str)
# slicing till the 2nd last element
data['Saraly (Int)'] = data['Salary'].str.slice(start, stop, step)
data.head()
|
cs |
3. Series.str.split()
특정 Seperator 나 Delimiter 를 기준으로 시리즈 내 각 원소를 쪼개고 싶을 때 Series.str.split() 를 사용합니다. 쪼개진 결과는 1)시리즈 내 리스트나 2) 여러 개의 칼럼으로 반환됩니다.
판다스도 기본 함수도 split() 를 지원하나 만약 split() 만 사용하게 되면 개별 원소 하나에만 적용됩니다. 시리즈 전체 원소에 대해 일괄적으로 적용하고 싶다면 앞서 계속 얘기한 것처럼 .str.split() 을 사용해야 합니다. 하기 파라미터와 함께 사용됩니다.
- Series.str.split(pat=None, n=-1, expand=False)
- pat: 구분기준, Seperator
- n: 쪼개지는 최대 개수를 의미, -1는 all 을 의미 (예를 들어 시리즈 원소 내에 공백이 여러 개 있는데 n=2 로 두면 첫번째, 두번째 공백까지만 split 됨)
- expand=True 일 경우, split 된 결과가 여러 칼럼으로 반환됨, False 일 경우 split 된 결과가 리스트 형태로 반환됨
이제 예제 데이터를 가지고 연습을 해보겠습니다. Team 열의 데이터를 가지고 알파벳 t 를 기준으로 앞 뒤로 split 을 해보려고 합니다.
data = pd.read_csv('/nba.csv')
data.dropna(inplace=True)
# 시리즈 내 t 글자가 보일 때마다 t를 기준으로 split 됨
data['Team'] = data['Team'].str.split('t', n = 1, expand=False)
data.head(10)
|
cs |
Team 의 데이터인 Boston Celtics 문자열이 t 를 기준으로 나뉜 것을 확인할 수 있습니다. expand=False 옵션을 두었기 때문에 리스트 형태로 반환되었습니다.
이번엔 Name 열에 있는 선수들의 이름을 First Name 과 Last Name 으로 나누어 따로 칼럼을 만들어보겠습니다.
- data['Name'].str.split(' ', n = 1, expand=True): 공백을 기준으로 나누고, expand=True 로 설정하여 split 된 결과가 여러 개의 칼럼으로 쪼개져 반환되게 하였습니다. 이를 new 객체에 할당합니다. 하기 스크린샷 참고하면 결과값을 보실 수 있습니다. Name 이 공백을 기준으로 2개의 열로 split 된 것을 확인할 수 있습니다. expand=True 를 하였기 때문입니다.
- new 의 0열은 data 데이터프레임의 First Name 칼럼에 1은 data 데이터프레임의 Last Name 칼럼에 할당합니다.
- 기존에 있던 Name 열은 삭제합니다.
이를 정리하면 하기와 같습니다.
data = pd.read_csv('/nba.csv')
data.dropna(inplace=True)
# 공백을 기준으로 쪼개고, expand=True 로 설정하여 여러 칼럼으로 반환되게 함, new 라는 문자열에 할당
new = data['Name'].str.split(' ', n = 1, expand=True)
# new 의 0번째 열을 data 데이터프레임의 First Name 열에 할당, 1번째 열은 Last Name 열에 할당
data['First Name'] = new[0]
data['Last Name'] = new[1]
data.drop(columns='Name', inplace=True) # 기존에 있던 Name 칼럼 삭제
data
|
cs |
4. Series.str.replace()
만약 시리즈 내 원소들의 특정 문자열을 다른 문자열로 치환하고 싶다면 어떻게 할까요? 그럴 때 사용하는 것이 str.replace() 입니다. 특정 문자열에 대한 치환 뿐 아니라, replace 를 사용하여 특정 정규 표현식 찾아내고 이를 다른 정규 표현식으로도 바꿀 수 있는 거 같습니다. 이 때는 Regex 에 True 값을 적용해야 합니다.
- Series.str.replace(pat, repl, n=-1, case=None, regex=True)
- pat: 대체될 문자열 혹은 정규 표현식
- repl: 대체할 문자열 혹은 정규 표현식
- n = 치환되는 문자열 개수, -1는 all 의미
- case = True 아님 False 가 옴.. case=False 면 case insensitivity, 즉, 대소문자 구별하지 않음을 의미
- Regex=True: pat 부분에 정규표현식을 인풋했음을 의미, True 아님 False 가 옴
예시로, Age 열에 있는 숫자 중 25.0 을 Twenty Five 로 치환해 봅시다. 매우 간단합니다. 파이썬의 기본함수 replace 처럼 사용하면 됩니다. 단, 시리즈이므로 역시 .str 를 함께 적용합니다.
data = pd.read_csv('/nba.csv')
# Age 열을 string 으로 변환 (.str 는 문자열에만 적용되기 때문)
data['Age'] = data['Age'].astype(str) # .str accessor only works with string values
# 25.0 을 문자열 Twenty Five 로 변환 data['Age'] = data['Age'].str.replace('25.0', 'Twenty Five')
data['Age'] |
cs |
이번엔, Team 의 데이터값 중 하나인 Boston Celtics 를 New Boston Celtics 를 치환해 봅시다.
data['Team'].str.replace('Boston', 'New Boston') 으로 입력할 수도 있지만, case=False 옵션을 적용해 봅시다. case=False 를 적용하면 대소문자 구별을 하지 않는 다는 의미 입니다.
data = pd.read_csv('/nba.csv')
# boston 문자열을 New Boston 으로 치환, 이 때 대소문자를 구별해야 하지 않으므로 case=False 로 지정
data['Team'] = data['Team'].str.replace('boston', 'New Boston', case=False)
# Team 열 value 가 New Boston Celtics 만 추리기
data.loc[data['Team'] == 'New Boston Celtics', :]
|
cs |
5. Series.str.cat()
이번엔 시리즈 원소들을 가지고 각 원소들을 서로 Concat (값들 합치기) 을 하는 법을 정리해 보겠습니다. 이 때 사용할 수 있는 것이 Series.str.cat() 입니다. 시리즈A.str.cat(시리즈B) 라면 시리즈A 내 각 원소와 시리즈 B 내 각 원소가 합쳐지게 되는 원리 입니다. 마찬가지로 .str 가 사용되며 str.cat() 에 사용되는 파라미터는 하기와 같습니다.
- Series.str.cat(others=None, sep=None, na_rep=None)
- Others: Concatenate 할 시리즈나 리스트
- sep: 두 개의 다른 문자열 혹은 값 사이의 구분자(Seperator)
- na_rep: 시리즈 내 Null value 가 왔을시 대체될 문자열
만약 시리즈 내 원소 중 Null 값이 있다면 이를 어떻게 대체할지 na_rep 옵션을 이용하여 지정해 주면 됩니다.
NBA 선수들의 Name 과 Team 의 값을 Concat 하여 Name_w_Team 이라는 신규 칼럼에 할당해 보겠습니다. 이 때 sep 옵션에 ', ' 을 지정하여 쉼표(,) 로 구분합니다.
data = pd.read_csv('/nba.csv')
data.dropna(inplace = True)
# Team 시리즈 값 복사
team = data['Team'].copy()
# Name 열 값과 Team 열 값 concat, 이 때 , 로 구분, 신규 칼럼에 할당
data['Name_w_Team'] = data['Name'].str.cat(team, sep=', ')
data.head()
|
cs |
6. Series.str.get()
만약 시리즈 내 각 원소의 특정 위치에 있는 일부만 반환하고자 할 때는 어떻게 해야 할까요? 그럴땐 Series.str.get() 을 사용하면 됩니다.
- Series.str.get(i)
- i : 추출하고자 하는 원소의 특정 위치, 인덱스 개념
NBA 선수들의 Name 중 첫번째 알파벳만 추출해 봅시다. 이럴 땐 data['Name'].str.get(0) 을 입력합니다.
data = pd.read_csv('/nba.csv')
data.dropna(inplace = True)
# string 으로 변환 data['Name'] = data['Name'].astype(str)
# Name 열 각 원소들 중 0번째만 추출하여 Name_first 칼럼에 할당 data['Name_first'] = data['Name'].str.get(0)
data.head()
|
cs |
Series.str.get() 을 이용하여 문자열의 일부를 추출할 수도 있지만 리스트의 일부를 추출할 수도 있습니다. 하기를 봅시다.
Team 이름의 각 원소를 Space 를 기준으로 쪼갰습니다. 그 결과는 리스트로 반환되었을 것입니다. 그리고 그 반환된 결과 중 첫번째 원소를 team_firstpart 에 두번째 원소를 team_secondpart 에 할당하였습니다.
예를 들어, Boston Celtics 중 첫번째인 Boston 은 team_firstpart 에 Celtics 는 team_secondpart 에 할당 되었습니다.
data = pd.read_csv('/nba.csv')
data.dropna(inplace = True)
# Team 이름을 space 를 기준으로 쪼갬 data['Team'] = data['Team'].str.split(' ', 1)
# 리스트로 반환된 결과 중 첫번째 원소, 두번째 원소를 각각 firstpart, secondpart 에 할당 team_firstpart = data['Team'].str.get(0)
team_secondpart = data['Team'].str.get(1)
print(team_firstpart)
print(team_secondpart)
|
cs |
Series.str. 를 활용할 수 있는 몇 가지 메소드를 정리해 보았습니다. 파이썬에 기본 함수와 겹치는 부분이 있지만 서두에도 밝혔듯 시리즈 내 각 원소에 모두 일괄로 적용되어야 하므로 str. 이 항상 같이 사용되어야 하는 점이 핵심입니다. 그 외에는 파이썬 내 기본 함수들과 사용법이 유사하기 때문에 어렵지는 않을 것입니다.
참고 웹사이트:
https://www.geeksforgeeks.org/
GeeksforGeeks | A computer science portal for geeks
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
www.geeksforgeeks.org
'데이터관련공부 > Python' 카테고리의 다른 글
Python | 람다(Lambda) 함수 정리 (0) | 2023.08.15 |
---|---|
Python | 시각화 (Visualization) (여러 그래프 for 문 이용하여 한 번에) (0) | 2023.08.14 |
Python | 시각화 (Visualization) (막대 그래프) (0) | 2023.07.25 |
Python | 칼럼 추출하기 (특정 조건을 만족하는 칼럼 포함) (0) | 2023.07.19 |
Python | Pandas 인덱싱(Indexing) 및 슬라이싱(Slicing) (0) | 2023.07.12 |