Pandas에서 Nested For Loops 해결하기(2)

Code Playground·2021년 10월 9일
0

pandas

목록 보기
2/2

리스트를 통해 데이터프레임 전체의 값을 바꾸는 것을 "vectorize한다"라고 표현하는 듯 하다. 그게 Pandas 연산 중에서도 가장 빠르다고 하니 어디 한 번 이용해보도록 하자.

# modify하고 싶은 컬럼의 변경 값을 저장할 리스트
# 이 리스트들의 길이는 최종적으로 df1의 길이와 같아야 한다.
# 그래야 한 번에 substitute 되니까
a_answer_list = []
b_answer_list = []
c_answer_list = []
d_answer_list = []

먼저 빈 리스트들을 컬럼 별로 만들어준다. 주석에 적어준 대로 이 리스트들이 바로 우리가 바꿔줄 df1의 데이터프레임 value들이 될 것이다.

# 필요한 컬럼의 값들을 리스트로 만들어줌
a_list = df1['A'].tolist()
b_list = df1['B'].tolist()
c_list = df1['C'].tolist()
d_list = df1['D'].tolist()
v_list = df2['V'].tolist()

여기서부터 리스트의 이름을 잘 만들어줘야 후에 헷갈리지 않고 리스트를 활용할 수 있다. 지금은 컬럼 이름이 단순하지만 컬럼 이름에 의미가 있는 경우 알아보기 쉽도록 리스트 이름을 정해주자.

# v_list와 비교해서 컬럼 A의 값 정해주기
for a in a_list:
   if a not in v_list:
    	a_answer_list.append(a)
   elif a in v_list:
    	a_answer_list.append(False)                    
    		

이렇게 iteration을 통해 값을 조건에 맞춰 인덱스 순서에 맞게 리스트에 넣어줄 수 있도록 한다.

boolean 값으로 넣어주면 처리가 조금 더 빠르기 때문에 먼저 True/False로 넣어두고 후에 replace 함수를 이용해 nan값으로 바꿀 수 있다. 이 작업을 A, B, C, D 컬럼에 모두 행해준다. 다른 컬럼 코드 실행은 건너뛰도록 하겠다. a를 b, c, d로 바꿔준 똑같은 코드를 돌리면 된다.

a_answer_list

Output: ['Sam', 'Michael', 'Chris', False]

이 코드를 실행한 후 a_answer_list를 확인해보면 'Kim'이 지워지고 False가 남은 것을 볼 수 있다! 다른 리스트들도 마찬가지로 df2['V']에 있는 이름들은 모두 False로 변해 있을 것이다.

그렇게 리스트를 완성하고 나면 마지막으로 데이터프레임의 값을 리스트로 바꿔치기하는 일만 남았다. 이 작업은 간단하다.

df1['A'] = a_answer_list
df1['B'] = b_answer_list
df1['C'] = c_answer_list
df1['D'] = d_answer_list

인덱스에 맞췄기 때문에 각 데이터프레임과 리스트의 길이는 일치한다. 이 코드를 실행하고 df1을 확인해보면...

df1:

False 값들이 생긴 걸 볼 수 있다! 와! 그러면 진짜 마지막으로 False 값을 nan값으로 바꿔주자.

df1.replace(False, np.nan, inplace=True)

이렇게 inplace=True 옵션을 써도 되지만 안전한 작업을 위해서는

df1 = df1.replace(False, np.nan)

도 좋아보인다. 아무튼 이 코드까지 실행하고 나면...

df1:

이렇게! False 값이 nan값으로 바뀐 걸 확인할 수 있다. 정말 긴 여정이었다...

예시를 만들다보니 내가 맞닥뜨렸던 문제와는 조금 다른 문제가 되긴 했는데 맥락은 비슷하다. For문을 두 세 번씩 겹쳐 돌리는 일은 지양하고, 근본적으로 다른 방향의 해결책을 찾아야 한다는 것인데 그 방법 중에는 리스트를 이용한 vectorization이 존재한다는 것이다(이렇게 일괄 처리하는 연산 모두를 vectorization이라고 부르는 것이 맞겠지...? 아니라면 지적해주시면 감사할 것 같다).

리스트가 너무 많아서 난잡하긴 한데 나는 아직 이것보다 좋은 방법을 찾지 못했다...ㅠㅠ 이 방법을 사용하니 내가 썼던 nested for loop에서 30분 걸렸던 프로세스가 4분으로 단축됐다. 리스트 최고~~~

혹시 틀린 부분이 있거나 이것 말고 더 좋은 방법이 있다면 부디! 알려주시길 바란다. 그럼 20k~

profile
도라에몽 갖고 싶다

0개의 댓글