카테고리 보관물: Python

Python

팬더로 큰 CSV 파일을 어떻게 읽습니까?

팬더에서 큰 CSV 파일 (약 6GB)을 읽으려고하는데 메모리 오류가 발생합니다.

MemoryError                               Traceback (most recent call last)
<ipython-input-58-67a72687871b> in <module>()
----> 1 data=pd.read_csv('aphro.csv',sep=';')

...

MemoryError: 

이것에 대한 도움이 필요하십니까?



답변

이 오류는 머신에 한 번에 전체 CSV를 DataFrame으로 읽을 수있는 메모리가 부족함을 나타냅니다. 한 번에 메모리에 전체 데이터 세트가 필요하지 않다고 가정하면 문제를 피하는 한 가지 방법 은 매개 변수 를 지정하여 CSV를 청크처리하는 것입니다 chunksize.

chunksize = 10 ** 6
for chunk in pd.read_csv(filename, chunksize=chunksize):
    process(chunk)

chunksize매개 변수는 청크 당 행 수를 지정합니다. (마지막 청크는 chunksize행 보다 적을 수 있습니다 .)


답변

청킹이 항상이 문제의 첫 번째 포트가되는 것은 아닙니다.

  1. 숫자가 아닌 데이터가 반복되거나 원치 않는 열로 인해 파일이 커 집니까?

    그렇다면 때때로 열을 범주로 읽고 pd.read_csv usecols 매개 변수 를 통해 필요한 열을 선택하여 메모리를 크게 절약 할 수 있습니다 .

  2. 워크 플로우에 슬라이싱, 조작, 내보내기가 필요합니까?

    그렇다면 dask.dataframe 을 사용 하여 슬라이스하고 계산을 수행하고 반복적으로 내보낼 수 있습니다. 청킹은 dask에 의해 자동으로 수행되며 팬더 API의 서브 세트도 지원합니다.

  3. 다른 모든 방법이 실패하면 청크를 통해 한 줄씩 읽으십시오.

    최후의 수단으로 팬더 또는 csv 라이브러리 를 통한 청크 .


답변

나는 이렇게 진행했다 :

chunks=pd.read_table('aphro.csv',chunksize=1000000,sep=';',\
       names=['lat','long','rf','date','slno'],index_col='slno',\
       header=None,parse_dates=['date'])

df=pd.DataFrame()
%time df=pd.concat(chunk.groupby(['lat','long',chunk['date'].map(lambda x: x.year)])['rf'].agg(['sum']) for chunk in chunks)


답변

큰 데이터의 경우 다음과 같은 라이브러리 “dask”를 사용하는 것이 좋습니다
.

# Dataframes implement the Pandas API
import dask.dataframe as dd
df = dd.read_csv('s3://.../2018-*-*.csv')

자세한 내용은 여기를 참조하십시오 .

또 다른 훌륭한 대안은 모든 기능이 팬더와 동일하지만 dask와 같은 분산 데이터 프레임 라이브러리를 활용하기 때문에 modin 을 사용 하는 것입니다.


답변

위의 답변은 이미 주제를 만족시키고 있습니다. 어쨌든 메모리에 모든 데이터가 필요한 경우 bcolz를 살펴보십시오. . 메모리의 데이터를 압축합니다. 나는 그것에 대해 정말 좋은 경험을했습니다. 그러나 팬더 기능이 많이 없습니다.

편집 : 물론 데이터의 종류에 따라 약 1/10 또는 orig 크기의 압축률을 얻었습니다. 누락 된 중요한 기능은 집계였습니다.


답변

데이터를 청크로 읽고 각 청크를 피클로 저장할 수 있습니다.

import pandas as pd
import pickle

in_path = "" #Path where the large file is
out_path = "" #Path to save the pickle files to
chunk_size = 400000 #size of chunks relies on your available memory
separator = "~"

reader = pd.read_csv(in_path,sep=separator,chunksize=chunk_size,
                    low_memory=False)


for i, chunk in enumerate(reader):
    out_file = out_path + "/data_{}.pkl".format(i+1)
    with open(out_file, "wb") as f:
        pickle.dump(chunk,f,pickle.HIGHEST_PROTOCOL)

다음 단계에서는 피클을 읽고 각 피클을 원하는 데이터 프레임에 추가합니다.

import glob
pickle_path = "" #Same Path as out_path i.e. where the pickle files are

data_p_files=[]
for name in glob.glob(pickle_path + "/data_*.pkl"):
   data_p_files.append(name)


df = pd.DataFrame([])
for i in range(len(data_p_files)):
    df = df.append(pd.read_pickle(data_p_files[i]),ignore_index=True)


답변

read_csv 및 read_table 함수는 거의 동일합니다. 그러나 프로그램에서 read_table 함수를 사용할 때는 구분 기호“,”를 할당해야합니다.

def get_from_action_data(fname, chunk_size=100000):
    reader = pd.read_csv(fname, header=0, iterator=True)
    chunks = []
    loop = True
    while loop:
        try:
            chunk = reader.get_chunk(chunk_size)[["user_id", "type"]]
            chunks.append(chunk)
        except StopIteration:
            loop = False
            print("Iteration is stopped")

    df_ac = pd.concat(chunks, ignore_index=True)