반응형

wPython에서 pandas pkg를 이용하여 Dataframe 작업을 할 때 열 생성/변경/삭제 작업이 많다.

단순한 열 생성/변경/삭제 작업의 경우 간단하지만, 다수 개의 조건하에 있는 열 변경 작업은 생각이 조금 필요하다.

오늘 원소 값 변경을 위해 삽질을 여러 번 하다가.. 발견한 조건에 따른 원소 값 변경 코드를 정리해본다.

1. Dataframe 생성

original dataframe으로 Name, Gender 열을 가진 간단한 df를 생성했다. 이후에는 새로운 열을 생성하고, 그 열에 대한 원소값을 변경할 것이다.

a = pd.DataFrame({'Name':['Jane','Young','Tester','Tester2'], 'Gender':['man','woman','woman','man']}) print('***** original dataframe *****') print() print(a)

2. 조건에 따른 Dataframe에 새로운 Column 생성

나는 python의 loc 와 str.contains 함수를 사용할 것이므로, 이것을 먼저 간단하게 알아보고 넘어간다.

x.loc: label(값)을 이용하여 values 그룹에 접근(indexing)하는 것.

아래 예시(Example)과 같이 label(값 = viper)에 따른 값들을 출력해주는 method이다.

str.contains: string에서 아주 유용한 함수로, 인자값에 따른 문자열을 찾아준다.

예를들어, a={"장미", "집", "배나무", "매화는 매실의 ", "가나다", "abc", "꽂", "꼽", "꽁", "꼿꼿"} 라는 배열에서 a.str.contains("꽃")을 실행하면 "꽃"을 포함한 모든 단어를 출력할 수 있다.

즉, '기업명' 이라는 열에서 'xx전자'라는 이름을 가진 기업명을 찾아 '업무분야' 라는 카테고리를 새로 만든 후, '전자'라는 값을 삽입한다고 치자. 그럴 경우 기업명엔 '삼성전자', 'LG전자', 'ABC전자'등 많은 값이 있을 지라도 이 분류는 '전자'로 처리될 수 있다.

그러면 이제 나의 예시에서 loc와 contains method를 함께 사용해본다.

a.loc[a['Gender'].str.contains("wo")]) # a['Gender']열에서 "wo"가 포함된 값의 grp을 찾는다.

그 결과값으로 1, 2번 값들이 출력된다.

그러면 이제 해당 값("wo")을 가진 그룹에 'category'라는 column을 추가하여 '여자'라는 값을 생성한다.

a.loc[a['Gender'].str.contains("wo"), 'category'] ='여자' print(a)

3. 기존 Dataframe에 새로운 조건 삽입

2번에서 category가 '여자'라고 설정된 a dataframe에 새로운 조건을 적용해본다.

a.loc[a['Gender'].str.contains("man"), 'category'] ='사람' #man이 포함된 경우 '사람'을 입력한다. print(a)

* np.where()

: 배열 요소를 검색해 인덱스를 반환. 검색 조건을 응용하여 True, False 형태로 많이 사용함.

(예시) 1. dataframe에서 '입사기관명/진학학교명' 값들의 대분류를 만들기 위해, 기존 df에 'Category' 열을 삽입하고, '화학' or '에너지' or 환경 키워드를 포함한 입사원들에 대해 '화학.에너지.환경'의 데이터를 category로 입력해준다.

1) 초기 dataframe의 행은 3511명의 data로 구성되어 있다. 3번 순번을 가진 사람은 'LG화학'에 입사했으므로 'Category'열에 '화학.에너지.환경'이라는 값을 가질 것이다.

2) '화학' or '에너지' or '환경' 키워드를 포함한 입사기관명/진학학교명을 찾아, 그 값이 포함되었을 경우 'True', 미포함했을 경우 'False'로 값이 생성된다.

em_df['Category'] = em_df['입사기관명/진학학교명'].str.contains('화학' or '에너지' or '환경') em_df.head()

3) 그리고 True값을 가진 열을 '화학.에너지.환경'으로 값을 치환시킨다.

em_df['Category'] = np.where(em_df['Category']==True,'화학·에너지·환경', em_df['Category']) em_df.head()

4) 치환이 잘 됐는지 확인해본다.

2, 49, 66, ... 번의 사람들이 화학/에너지/환경 분야에 취업또는 진학했다.

*** 하지만 이렇게 np.where, str.contains을 사용해서는 여러 조건에 대한 값을 변경할 수 없다.

왜냐? 화학.에너지.환경으로 이미 바뀐 값들이 텔레캅/미작성에 대해 True/False를 다시 하게되면,

이전 바뀌었던 화학.에너지.환경은, 텔레캅/미작성 조건에서는 False가 되어버리기 때문이다.

+ str.contains에서 or을 쓸 경우 앞의 값만 체크가 된다! '미작성'값 Category는 '테스트중'으로 바뀌지 않았다.

즉, 여러 조건을 중첩하여 값을 바꿀 때엔 아래와 같이 loc를 사용해야한다.

em_df.loc[em_df['입사기관명/진학학교명'].str.contains("화학"), 'category'] ='화학' em_df.loc[em_df['입사기관명/진학학교명'].str.contains("텔레캅"), 'category'] ='테스트중' em_df.head()

오늘 몇 시간 삽질한 결과.... 다행히 정리됐다.

구글링을 많이 해봤지만 loc를 여러 조건을 통해 중첩시키는 예제는 없고,

중첩되는 조건을 쓰는 건 쉬운 숫자값들밖에 없었다.

+ 내용은 제대로 안알려주고 광고만 덕지덕지 붙은 티스토리, 네이버블로그 들까지...

나는 정말 나뿐만 아니라 남들에게도 도움이 되는 글을 쓰고싶다. 

오늘의 삽질 끄읕!!

 

반응형

+ Recent posts