스크립트
00:00:00Pandas의 가장 강력한 경쟁자가 버전 2.0 출시를 앞두고 있습니다.
00:00:04Polars 업데이트가 임박했는데, 가장 큰 변화는 아마 예상치 못한 부분일 겁니다.
00:00:09기본적으로 기존에 작성한 모든 쿼리가 다른 엔진에서 동작하게 됩니다.
00:00:14코드 한 줄 바꾸지 않고 말이죠.
00:00:15또한 Polars는 입력한 순서대로 행이 반환된다는 보장을 더 이상 하지 않습니다.
00:00:19퇴보처럼 보일 수 있지만 실제로는 아니며, 첫 번째 변화를 가능하게 만든 대가입니다.
00:00:24Polars가 2.0으로 한층 더 세를 넓히며 Pandas를 바짝 위협하고 있습니다.
00:00:30역대 가장 큰 업데이트를 함께 살펴보겠습니다.
00:00:37자, 그동안 Pandas는 거의 모든 데이터 작업에서 표준으로 자리 잡아 왔습니다.
00:00:43단순하고 대중적이라 데이터 분석뿐만 아니라 머신러닝에서도 핵심적인 역할을 하죠.
00:00:49그러다 얼마 전 Polars가 등장했습니다.
00:00:51Polars는 항상 Pandas보다 빨랐는데요.
00:00:53그 부분도 이따가 다루겠습니다.
00:00:54이제 이번 대규모 2.0 업데이트를 통해 더 널리 채택될지도 모릅니다.
00:01:00간단히 배경을 말씀드리면, Polars에는 조용히 존재해 온 두 개의 엔진이 있습니다.
00:01:05대부분이 사용해 온 방식은 인메모리(in-memory) 엔진입니다.
00:01:08일종의 대형 창고라고 생각하시면 됩니다.
00:01:10창고 바닥 전체에 데이터셋을 전부 올려둔 뒤, 쿼리의 각 단계를 데이터 전체에 대해 실행하죠.
00:01:17그리고 이건 엄청나게 빠릅니다.
00:01:19모든 데이터가 RAM에 들어가는 동안에는 말이죠.
00:01:21스트리밍 엔진은 동작 방식이 다릅니다.
00:01:23하나의 거대한 창고 대신, 조립 라인에 가까운 방식으로 작동합니다.
00:01:27Polars는 데이터를 개발진이 Morsel이라 부르는 작은 조각들로 잘라냅니다.
00:01:32이 조각들은 CPU 캐시에 딱 맞도록 크기가 맞춰집니다.
00:01:36그러고 나서 쿼리 플랜을 따라 전달되는 것이죠.
00:01:39이제 전체 데이터셋이 처리되길 기다릴 필요 없이 쿼리의 각 부분이 계속 진행될 수 있습니다.
00:01:43속도가 향상되는 비결이 바로 여기에 있습니다.
00:01:44궁극적으로는 메모리보다 큰 데이터를 다루기 위한 방향이기도 합니다.
00:01:49하지만 주의할 점이 있습니다.
00:01:50조립 라인에 작업자 8명이 있을 때, 먼저 시작했다고 먼저 끝나는 것은 아닙니다.
00:01:56Polars도 마찬가지입니다.
00:01:58따라서 2.0에서는 조인, 그룹화, 언피벗 등에 대해 문서에서도 말 그대로
00:02:04행 순서를 더 이상 보장하지 않습니다.
00:02:06명시적으로 요청하지 않는 이상 말이죠.
00:02:08작업 흐름을 빨라지게 하는 코딩 툴에 관심이 있다면 꼭 구독해 주세요.
00:02:11유용한 영상이 지속적으로 업로드됩니다.
00:02:13자, 그럼 실제 모습이 어떤지 보여드리겠습니다.
00:02:15uv pip install --pre polars 명령어를 입력하겠습니다.
00:02:18--pre 플래그를 기억해 두세요.
00:02:20잠시 후에 다시 설명해 드리겠습니다.
00:02:22좋습니다.
00:02:222, 1, 0 키를 가진 LazyFrame이 있습니다.
00:02:27다른 프레임과 Left Join을 한 뒤 collect를 호출해 보겠습니다.
00:02:32결과를 한번 보세요.
00:02:34Polars 1과 동일한 코드입니다.
00:02:35순서가 더 이상 보장되지 않습니다.
00:02:37똑같은 코드인데 동작이 달라진 것이죠.
00:02:39이제 Join 연산에 maintain_order=”left”를 추가해 봅니다.
00:02:43다시 실행해 보겠습니다.
00:02:44여기서 다시 돌려볼게요.
00:02:45그러면 원래의 순서가 돌아옵니다.
00:02:47즉, Polars가 데이터를 무작위로 섞는 것이 아닙니다.
00:02:51순서가 중요하다면 직접 지정하라는 식입니다.
00:02:54직접 명시를 해줘야 하죠.
00:02:56그리고 또 세심한 디테일이 있습니다.
00:02:58쿼리에 explain() 함수를 실행해 보세요.
00:03:01동작 방식을 숨기지 않습니다.
00:03:03어디를 봐야 하는지만 알면 됩니다.
00:03:05이것이 가장 큰 동작상의 변화입니다.
00:03:06하지만 2.0은 신기한 게, 딱히 기능 추가 중심의 릴리즈가 아닙니다.
00:03:10사실상 리팩토링 및 정리 작업에 가깝습니다.
00:03:12그리고 정리된 분량이 제법 많습니다.
00:03:15원래 Pandas 스타일이었던 read_csv는 제거되고 내부적으로 scan_csv().collect() 방식을 사용하는 형태로 정리되었습니다.
00:03:22LazyFrame.profile()도 삭제되었습니다.
00:03:25melt는 이제 unpivot으로 변경되었습니다.
00:03:28join_nulls는 nulls_equal로 바뀌었습니다.
00:03:30정수형(Integer)을 범주형(Categorical)으로 바로 캐스팅하는 기능은 제거되었습니다.
00:03:35대신 cat.to()를 사용하여 전환할 수 있습니다.
00:03:38문자열을 Date 유형으로 직접 캐스팅하는 기능도 제거되었습니다.
00:03:41str.to_date()를 사용해야 하죠.
00:03:43부호 있는 정수와 부호 없는 64비트 정수를 더할 때, Float으로 변경되어 정밀도를 조용히 잃는 대신 Int128 타입을 반환합니다.
00:03:53변경 사항은 이뿐만이 아닙니다.
00:03:55concat 함수도 개선되었는데요.
00:03:57의도를 임의로 추측하는 대신, 높이(행 수)가 일치하지 않으면 거부합니다.
00:04:02이는 사실 Polars 측의 현명한 선택입니다.
00:04:05제거된 기능을 호출하면 AttributeRemovedError가 발생합니다.
00:04:09에러 메시지를 통해 대체된 기능을 알려주죠.
00:04:12melt를 호출하면 에러 메시지에서 index와 on 인자를 써서 unpivot을 사용하라고 명시해 줍니다.
00:04:17이 모든 에러 메시지가 사실상 올바른 사용 가이드 역할을 합니다.
00:04:20코드를 실행하고, 오류가 나면 메시지에 따라 해당 부분만 고치며 계속 진행하면 됩니다.
00:04:26이것이 많은 이들이 Polars를 메인 도구로 채택하게 된 이유이기도 합니다.
00:04:31Pandas는 수많은 문제를 런타임 시점으로 미룹니다.
00:04:35Polars는 이러한 방식으로 문제들을 사전에 잡아내고자 합니다.
00:04:37collect_schema()를 호출하면 단 한 행도 읽기 전에 타입 오류를 미리 파악할 수 있습니다.
00:04:44앞으로 벌어질 상황을 미리 예측하는 것이죠.
00:04:47그리고 점점 더 효율적으로 발전하고 있습니다.
00:04:48그렇다면 Polars의 위치는 정확히 어디일까요?
00:04:50우선 DuckDB는 SQL 중심입니다.
00:04:53Polars는 Python용으로 구축된 표현식 API이고요.
00:04:56Dask와 Spark도 있습니다.
00:04:58그것들은 분산 처리용이죠.
00:04:59Polars는 단일 머신 처리에 집중합니다.
00:05:01오픈소스 라이브러리 자체는 오픈소스이지만,
00:05:04Polars Cloud는 그렇지 않습니다.
00:05:05이 핵심적 차이는 성능 부분에 들어가면 중요해집니다.
00:05:09발표에 따르면 새 스트리밍 엔진이 무려 5배나 더 빠르다고 합니다.
00:05:13몇 년 동안 Polars를 써본 결과 Pandas보다 빠르긴 하지만, 5배 같은 대단한 속도 향상은 경험해보지 못했는데요.
00:05:21더 큰 데이터셋에서 한번 테스트해보세요.
00:05:23확실히 속도 차이를 체감할 수 있을 겁니다.
00:05:25실행이나 데이터셋마다 다르겠지만, 체감 성능과 런타임 수치로 확실히 확인하실 수 있습니다.
00:05:30그리고 이것이 이번 릴리즈에서 가장 중요한 차이점일 것입니다.
00:05:34엔진이 디스크로 데이터를 넘겨 처리하는 진정한 아웃 오브 코어(Out-of-core) 실행 기능은 아직 반영되지 않았습니다.
00:05:40따라서 현재의 스트리밍은 청크(chunk) 단위 청크 및 파이프라인 처리를 의미합니다.
00:05:43데이터셋 크기가 마법처럼 RAM보다 커질 수 있다는 뜻은 아닙니다.
00:05:465배라는 수치는 Polars 측의 자체 기대치입니다.
00:05:50포스트 어디에도 벤치마크 표는 제공되지 않습니다.
00:05:53그리고 솔직히 대부분은 크게 개의치 않는 분위기입니다.
00:05:55많은 사용자가 화려함은 없어도 실용적인 이번 업데이트에 만족해하는 듯합니다.
00:05:59기능이 대거 쏟아져 나오지 않아서,
00:06:01새로 익혀야 할 것도 없습니다.
00:06:02코딩 중에 발생하는 에러 메시지가 무얼로 대체해야 할지 친절히 알려주니까요.
00:06:07하위 호환성을 깨고, 코드를 정리하며, 시맨틱 버저닝(SemVer) 규칙을 정석대로 따르는 모습입니다.
00:06:12하지만 두 가지 불만이 반복적으로 제기되고 있습니다.
00:06:14첫 번째는 행 순서 문제입니다.
00:06:15maintain_order의 기본값이 false이면 코드에 치명적인 버그가 생길 수 있습니다.
00:06:19아무런 에러도 발생하지 않기 때문이죠.
00:06:21연산 수치 자체는 완벽히 맞을 수 있습니다.
00:06:23단지 다른 순서의 행에 매핑되어 있을 뿐입니다.
00:06:26이건 예외 발생보다 알아채기가 훨씬 어렵습니다.
00:06:29두 번째 불만은 '스트리밍'이라는 용어입니다.
00:06:32아직 완전한 아웃 오브 코어가 아닌 엔진에 사용하기엔 혼란스럽다는 의견입니다.
00:06:38그리고 실제 릴리즈 후보(RC) 버그들도 존재합니다.
00:06:41RC가 공개된 이후 높은 우선순위 이슈가 발생했는데,
00:06:44스트리밍 엔진에서 group_by_dynamic 사용 시 datetime 범위를 벗어나는 오류가 납니다.
00:06:49limit 메소드를 호출할 때도,
00:06:51Join 이후 limit이 조기 종료되지 않는 문제가 있습니다.
00:06:54또한 문자열을 Datetime으로 변환 시 에러를 내는 대신 null을 반환하기도 합니다.
00:06:58아까 --pre 설치 옵션을 기억해두라고 말씀드린 이유가 이것 때문입니다.
00:07:022.0 이전의 사전 버전이니까요.
00:07:04이건 어디까지나 릴리즈 후보(RC) 버전입니다.
00:07:06그리고 지금은 딱 그 단계처럼 동작합니다.
00:07:08그건 괜찮습니다.
00:07:09그렇죠?
00:07:09아직 정식 완제품 버전은 아니니까요.
00:07:11한 가지 더 말씀드리면,
00:07:12Rust 크레이트는 여전히 0.55 버전입니다.
00:07:15따라서 Rust 환경에서 Polars를 사용하는 경우 아직 2.0을 쓸 수 없습니다.
00:07:19하지만 대부분의 개발자분들은 Python을 사용할 것으로 생각됩니다.
00:07:24그렇다면 지금 업그레이드해야 할까요?
00:07:25새 프로젝트라면 저라도 적용할 것 같습니다.
00:07:27맞죠?
00:07:27우리는 새로운 기술과 업데이트에 적응해 나가는 법이니까요.
00:07:30기존 파이프라인이 이미 sink_parquet이나 sink_csv를 쓰고 있었다면 사실상
00:07:34이미 스트리밍 방식을 계속 써오고 계셨던 셈입니다.
00:07:36하지만 관망하는 게 나은 유스케이스들도 있습니다.
00:07:39그렇죠?
00:07:39코드가 행 순서에 의존적이라면 막연히 업그레이드하지 마세요.
00:07:43뒤에 sort 연산이 붙어있지 않은 group_by 구문들을 grep으로 검색해 보세요.
00:07:47group_by_dynamic을 쓰는 중이라면 안정화될 때까지 기다리는 것을 추천합니다.
00:07:51어쨌든 어디로 향하고 있는지 방향성을 보는 것은 흥미롭습니다.
00:07:54이것이 결국 2.0이 되겠지만, 아직 정식 출시는 아닙니다.
00:07:57미리 적응해보실 수는 있겠지만 아직 완전하진 않죠.
00:08:00제가 계속 생각하게 되는 점은 이번 릴리즈가 참 이례적이라는 것입니다.
00:08:03Polars 2.0은 새로운 기능을 전혀 추가하지 않았습니다.
00:08:07그러면서도 기존 코드가 작동하는 방식에는 변화를 줍니다.
00:08:10새 엔진은 내 컴퓨터에서 더 빠르긴 하지만, 5배까지 빠르진 않았습니다.
00:08:14따라서 2.0이 기대되는 이유는 새로운 기능이 대거 추가되어서가 아닙니다.
00:08:18메이저 버전 업그레이드를 통해 우리가 이미 사용 중인 모든 기능의 기반을
00:08:24대대적으로 정리 정돈하기에 기대되는 것입니다.
00:08:26BetterStack의 Josh였습니다.
00:08:28이와 같은 코딩 팁과 유용한 정보를 더 원하시면 꼭 구독 부탁드립니다.
00:08:30다음 영상에서 뵙겠습니다.
커뮤니티 글
아직 글이 없습니다. 이 영상에 대한 첫 번째 글을 작성해 보세요!
이 영상에 대해 글쓰기