파이썬 및 판다스는 분석가 입장에서 개발적인 지식이 많지 않아도

코드를 활용해서 분석할 수 있게끔 도와주는 훌륭한 도구이다.

 

대용량 데이터를 분석하다보면 결국 한정된 서버자원으로 많은 데이터를 다뤄야하는 순간이 오고,

이 때 분산처리를 활용하는 등의 방법도 있지만,

기존에 판다스로 구성된 코드라면 여러가지 방법으로 메모리 사용량을 줄일 수 있다.

 

여기에 대한 아이디어는 아래 영상을 많이 참고했다. (가급적 이 글보다 영상을 정독하는 것을 추천한다.)

→ https://www.youtube.com/watch?v=0Vm9Yi_ig58

 

위 영상에 나오는 내용 중 내가 채택한 방식은 아래 두가지이다.

 - 데이터프레임에 사용할 컬럼 타입을 효율적으로 지정

 - 파일 저장 포맷을 변경 (csv → parquet)

 

 

1. reduce memery usage

 - 각 컬럼의 전체 값을 스캔한 후 최대, 최소값에 따라 최소한의 가능한 타입을 지정해준다. (float, int)

   이렇게 했을때 약 20~70% 까지 메모리 사용량이 감소하는 것을 확인했다.

   object 타입은 category 타입으로 지정해주면 메모리 사용량이 감소한다.

   메모리 사용량을 측정할 때는 파이썬 패키지 중 memory_profiler를 활용했다.

   (여담이지만 나중에 고생하는 것보다 최초 코드 작성 시에 코드 레벨로 메모리를 프로파일하면 좋았을 것 같다.)

 

 - 데이터가 작은 경우 타입을 조정했을 때 오히려 메모리 사용량이 커지는 경우도 존재했는데,

   무시 가능한 수준으로 보인다.

 

 - 스캔하여 적정한 타입을 찾는 것도 시간이 걸리는 일이라,

   해당 데이터에 얼마나 자주 접근해야하는지 등을 기준으로 두어 위 방법을 적용할지 선택하면 좋을 것이다.

 

2. pyarrow parquet 파일로 저장할 때 halffloat (float16) 타입은 저장이 불가한 오류

 - 위 방식으로 최소한의 타입을 지정하다보면 float16으로 컬럼타입을 지정해주는 경우가 있다.

   이 상태로 판다스의 to_parquet() 기능으로 저장하면 halffloat 타입은 지원하지 않는다는 오류가 발생한다.

   이 경우의 조치 방식은 두가지이다.

   1) float16 > float32 로 변경 후 저장 : 이 방식은 간단하지만 최초 메모리 사용량을 줄이고자 했던 취지에 반한다.

   2) pyarrow에서 engine='fastparquet' 활용

      - pyarrow로 데이터를 처리할 때 엔진을 pyarrow와 fastparquet 중 선택할 수 있다.

        default는 pyarrow로 설정되어 있는데, 필요한 경우 fastparquet을 엔진으로 사용할 수 있다는 걸 알아두면 좋다.

 

 

- 참고 : Parquet에서 Unhandled type for Arrow to Parquet schema conversion: halffloat 이 발생할 때 (velog.io)

Airflow는 목적에 따라 직렬, 병렬로 Task를 배치 및 실행 가능하다.

 

그 중 Dynamic Tasks는 Dag에서 병렬의 개수를 미리 정하지 않아도,

Task가 실행하는 메서드와 연결되어 유연한 병렬 Task 실행을 도와준다.

 

이 때 Command 생성을 위해 사용하는 메서드에 @Task 데코레이터를 사용해 개별 Task를 생성할 수 있고,

데코레이터 없이 메서드를 생성한 후, 실행하는 Operator만 운영할 수도 있다.

 

Command Task → Dynamic Tasks 구조로 연결된 경우 앞선 Command Task가 정상적으로 수행되면

여기서의 xcom 결과를 받아 따라오는 Dynamic Task가 실행되어야 하지만 Skip 되는 에러가 발생.

 

결론적으로 Command Task의 결과가 None 값을 보내주면

Command Task는 Success로 마킹한 채로 Dynamic Task로 넘어가지만,

Dynamic Task에서 실행할 병렬 Task는 0개이므로, 이 전체 Tasks는 Skipped로 처리된다.

 

어느 Task에서도 에러로 표기해주지 않아 문제 원인을 정확히 파악하는데 시간이 많이 걸렸다.



데이터->결과로 가는 것이 아니라
목적->데이터->결론으로 가는 것이다.

분석 목적을 명확히 하지 않으면, 있는 데이터만으로 짜맞추기만 하고, 실제로 필요한 분석을 하지 못할 수 있다.

문제를 해결할 때 정확한 단 하나의 정답이 존재하는게 아니다. 스스로 정의한 문제를 표현하고, 해결하기에 가장 적합해보이는 결론에 도달해야 한다.

결과와 결론은 다르다. 단순히 수치가 얼마나 증가했고, 평균이 얼마이고를 알고 싶은 것이 아니다. 실제로 어떤 변화가 있었고, 그에 따라 어떤 액션을 해야할지를 시사하는 것이 더욱 중요하다.

문제 > 원인 > 해결방안 순서로 간다.
원인을 파악하지 않고 문제에서 바로 해결방안으로 가지 않도록 주의한다. 그러다간 포괄적이고 의미없는 해결방안만 나올 것이다.
가능한 넒은 범위에서 원인을 떠올리고, 가설이 실제로 맞는지 데이터로 증명한다. 그리고 거기에 따른 해결방안을 연결할 수 있다면 보다 실천가능한 실질적인 해결 방안에 도달할 수 있다.

원인을 떠올릴 때 각 가설별로 여러 단계의 왜를 걸쳐 고민할 필요가 있다. 피상적으로 드러난 것이 실질적인 원인이라기 보단 더 근원적인 원인에 의한 현상일 수 있다.

어쨌든 데이터를 보기 전에 풀고자하는 문제가 무엇인지 명확히 해야한다.

+ Recent posts