큰 csv 파일을 처리하는 빠른 Pandas 및 Dask 비교. 지금 실행할 수 있는 실제 사례!

색인



  • Introduction

  • Environment preparation and data download

  • Running the comparison

  • Conclusion and final thoughts

  • 이 글을 쓴 이유에 대해 이야기를 시작하기 전에...



    이 첫 번째 부분에는 기술적인 내용이 포함되어 있지 않으므로 원하는 경우 소개로 바로 이동할 수 있습니다.

    이 기사의 주요 독자는 Pandas 대신 Dask를 사용해야 하는 이유와 시기에 대해 이해하려는 사람들입니다.

    이 기사의 주요 아이디어는 빠르게 진행하고 몇 가지 유용한 정보를 가지고 떠날 수 있다는 것입니다. 필요한 모든 것, 데이터 및 사용된 모든 명령을 다운로드하고 실행할 수 있습니다.

    비교는 Dask가 Pandas와 비교되는 것이므로 복사 붙여넣기가 아니라 따라야 할 Pandas 및 데이터 프레임에 약간 익숙해져야 합니다. 또한 특히 가상 환경에 대한 Python 지식이 필요합니다.

    Dask 또는 이와 유사한 기술에 대한 기사를 읽고 데이터를 사용할 수 없을 때 정말 짜증이 납니다. 더 짜증나는 것은 비교가 실제 세계에서는 절대 볼 수 없는 가짜 행복한 작은 데이터가 있는 장난감 예를 기반으로 하는 경우입니다. 이것은 그것을 해결하기 위한 나의 시도입니다.

    1. 소개

    Before we start you must:

    • Have python 3.5 or older installed with venv installed
    • At the moment a Linux-based system or a little bit of knowledge to translate the commands (I don't have a Windows machine close but give me a shout if you want me to translate the non-compatible commands)
    • That's it!

    The main thing to understand is that Dask is made out of two parts. A Dynamic task scheduler (something to schedule and lunch Dask tasks to process data and other things) and a data collection part. This second part is what you can directly compare to Pandas.

    You can think about it as a DataFrame that you can divide into sections and run each section in parallel in a different location. You could do that manually by subdividing a Pandas DataFrame and call some type of async function. Dask does that for you out of the box.

    Now the important bit, sometimes using Pandas is a better idea (better performance, more convenient etc). One of the main variables that influences whether you will get better performance in Pandas or Dask is the size of your data. We will now compare both in exactly this aspect.

    Please note that this is a complex topic and many variables will influence this decision but hopefully this article will get you started!

    2. 환경 준비 및 데이터 다운로드

    We are going to create a virtual environment, install Pandas, Dask and Jupyter Notebooks (this last one just to run our code).

    We will now create the main folder called pandasdask and a virtual environment called venv inside:

    mkdir pandasdask
    cd pandasdask
    python3 -m venv venv
    

    Now we will activate the virtual environment and install the packages we are going to need

    source venv/bin/activate
    pip install "dask[complete]==2.27.0" pandas==1.1.2 jupyter==1.0.0
    

    When I was installing it, some wheels failed but the packages were installed correctly nonetheless.

    Before we move on to our notebook, let's download the data we are going to use. We will use the uk gov housing price paid data. Make sure you read the usage guidelines here https://www.gov.uk/government/statistical-data-sets/price-paid-data-downloads#using-or-publishing-our-price-paid-data

    저작권 면책 조항:

    HM Land Registry 데이터 © Crown 저작권 및 데이터베이스 권리 2020을 포함합니다. 이 데이터는 Open Government License v3.0에 따라 사용이 허가됩니다.

    2019년의 모든 데이터와 지금까지 기록된 모든 데이터를 다운로드합니다. 이 두 번째 파일은 작성 당시(2020년 9월) 3.6GB로 Dask의 기능을 보여줄 수 있습니다.

    mkdir data
    cd data
    wget http://prod.publicdata.landregistry.gov.uk.s3-website-eu-west-1.amazonaws.com/pp-2019.csv
    wget http://prod.publicdata.landregistry.gov.uk.s3-website-eu-west-1.amazonaws.com/pp-complete.csv
    cd ..
    


    데이터 폴더를 만들고 이 폴더로 이동하여 데이터를 다운로드하고 이제 디렉토리의 루트로 돌아갑니다.

    3. 비교 실행

    Now, let's start jupyter notebook by running (make sure your virtual environment is activated)

    jupyter notebook
    

    Then create a new notebook and copy these sections into separated sections.

    First we import the libraries we are going to need

    import pandas as pd
    import time
    import dask
    import dask.dataframe as dd
    from dask.delayed import delayed
    import time
    from dask.distributed import Client, progress
    

    Then we define our data location and the columns names

    one_year_data = "data/pp-2019.csv"
    all_data = "data/pp-complete.csv"
    columns = ["transaction", "price", "date", "postcode", "prop_type", "old_new", "duration", "paon", "saon", "street", "locality", "city", "district", "county", "ppd_cat", "rec_status"]
    

    Now we run the Pandas version

    start = time.time()
    df = pd.read_csv(one_year_data,  header=0, names=columns)
    df_by_county = df.groupby("county")["price"].sum()
    print(df_by_county)
    end = time.time()
    print("time elapsed {}".format(end-start))
    

    Once that finishes, we initialise the Dask workers. This is were you can start playing with different configurations. I'm going to use 4 workers and 4 threads because it suits my particular architecture. I recommend you to change these settings and see what happens when you run the code afterwards. Try matching the workers to your cores and changing the number of threads for example.

    client = Client(threads_per_worker=4, n_workers=4)
    client
    

    You can click in the link that appears when running this command to have a look at how thing are being processed (the link will be output when running the command in pandas).

    Finally, we run the Dask version of the code. Here I'm using a blocksize of 32 MB. Again this is something you should change to 16 or 64 to see the difference it makes.

    start = time.time()
    df = dd.read_csv(one_year_data,  blocksize=32 * 1024 * 1024, header=0, names=columns)
    df_by_county = df.groupby("county")["price"].sum().compute()
    print(df_by_county)
    end = time.time()
    print("time elapsed {}".format(end-start))
    

    Here are results. For the one_year_data file, I got:

    pandas - time elapsed 2.32 seconds (rounded)
    dask - time elapsed 1.37 seconds (rounded)
    

    We are already seeing a gain. More fundamentally, we should be seeing a much large gain on the amount of memory we are using. You can have a quick approximate look at this by using a command such as htop or a resources monitor. Now, you should run this same exercise several times with the same and different parameters to look for an average rather than a punctual result. I found my results were fairly stable when doing this.

    WARNING!!!! THE NEXT STEP MIGHT USE ALL YOUR COMPUTER'S MEMORY AND CRASH IT. MAKE SURE YOU HAVE SAVED ALL PROGRESS AND HAVE ENOUGH MEMORY TO LOAD THE 3.6 GB FILE (you will need around 10 GB for this).

    Now, let's run the same code but processing the large all data file. Your code should look like this:

    start = time.time()
    df = pd.read_csv(all_data,  header=0, names=columns)
    df_by_county = df.groupby("county")["price"].sum()
    print(df_by_county)
    end = time.time()
    print("time elapsed {}".format(end-start))
    

    and for dask.

    start = time.time()
    df = dd.read_csv(all_data,  blocksize=32 * 1024 * 1024, header=0, names=columns)
    df_by_county = df.groupby("county")["price"].sum().compute()
    print(df_by_county)
    end = time.time()
    print("time elapsed {}".format(end-start))
    

    The results

    pandas - time elapsed 55.36 seconds (rounded) (around 10GB memory used)
    dask - time elapsed 19.6 seconds (rounded) (around 4.5 GB memory used)
    

    That is a larger difference and it is what you would expect by running the process in parallel.

    If your machine ran out of memory (it runs in mine but I have 32 GB of ram), try using a smaller file by dividing the file using the following command. This command will divide in approximately 4 sections each of a maximum of 7000 lines

    split -l 7000000 data/pp-complete.csv data/half_data.csv
    

    4. 결론 및 최종 생각

    We saw considerable gains in the larger file by using Dask. Pandas can be made more efficient and to run "chunks" as well but the main idea was to illustrate out of the box "vanilla" behaviour. You can read more about this here:

    https://stackoverflow.com/questions/25962114/how-do-i-read-a-large-csv-file-with-pandas

    이것은 매우 복잡한 주제이며 Dask가 모든 문제를 해결할 것이라고 결론을 내리기 전에 고려해야 할 많은 요소가 있음을 기억하는 것이 중요합니다. 예를 들어 추가 모니터링이 필요할 수 있는 다른 복잡한 설정입니다.

    또한 파일 크기(Pandas는 약 10MB 이하의 파일에서 Dask를 능가해야 함)와 아키텍처에 따라 크게 달라집니다. 예를 들어 테스트할 흥미로운 것 중 하나는 컴퓨터에서 Slack이나 스팸성 웹 페이지(여기서는 타블로이드가 이상적임)와 같은 무거운 것을 실행하고 연습을 다시 실행하는 것입니다. 이미 다른 프로세스와 함께 몇 개의 코어를 꺼내고 있다면 Pandas와 Dask의 차이가 상대적으로 줄어들 수 있음을 알 수 있습니다(Pandas는 단일 코어 프로세스임). 어떤 경우에는 작은 파일에서 Pandas가 Dask보다 빠르게 실행되는 것을 보았습니다.

    이 간단한 실습을 즐기셨기를 바랍니다. 이제 더 나은 지식을 쌓을 수 있는 더 좋은 위치에 있습니다.

    좋은 웹페이지 즐겨찾기