[python] Pandas read_csv 사용시 메모리 오류

나는 큰 csv 파일을 pandas 데이터 프레임으로 읽는 매우 간단한 것을 시도하고 있습니다.

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

코드는으로 실패 MemoryError하거나 종료되지 않습니다.

작업 관리자의 메모리 사용량은 506Mb에서 중지되었으며 5 분 동안 변경 사항이없고 CPU 활동이없는 프로세스에서 중지했습니다.

pandas 버전 0.11.0을 사용하고 있습니다.

파일 파서에 메모리 문제가 있었다는 것을 알고 있지만 http://wesmckinney.com/blog/?p=543 에 따르면 이 문제가 해결 되어야합니다.

내가 읽으려고하는 파일은 366Mb이고, 파일을 짧게 (25Mb) 줄이면 위의 코드가 작동합니다.

또한 0x1e0baf93 주소에 쓸 수 없다는 팝업이 나타납니다.

Stacktrace :

Traceback (most recent call last):
  File "F:\QA ALM\Python\new WIM data\new WIM data\new_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 216, in _read
    return parser.read()
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\io\parsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\frame.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:\Program Files\Python\Anaconda\lib\site-packages\pandas\core\internals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

약간의 배경 지식-저는 사람들에게 파이썬이 R과 똑같이 할 수 있다는 것을 확신 시키려고 노력하고 있습니다.이를 위해 저는 R 스크립트를 복제하려고합니다

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

R은 위의 파일을 잘 읽을 수있을뿐만 아니라 for 루프에서 이러한 파일 중 여러 개를 읽은 다음 데이터로 일부 작업을 수행합니다. 파이썬에 그 크기의 파일에 문제가 있다면 나는 잃어버린 전투와 싸울 수 있습니다 …



답변

Windows 메모리 제한

Windows에서 32 비트 버전을 사용할 때 파이썬에서 메모리 오류가 많이 발생합니다. 32 비트 프로세스 기본적으로 2GB의 메모리 만 사용 하기 때문 입니다.

메모리 사용량을 줄이는 방법

Windows에서 32 비트 파이썬을 사용하지 않지만 csv 파일을 읽는 동안 메모리 효율성을 향상시키려는 경우 트릭이 있습니다.

pandas.read_csv 기능이 라는 옵션을합니다 dtype. 이를 통해 팬더는 CSV 데이터에 어떤 유형이 있는지 알 수 있습니다.

작동 원리

기본적으로 pandas는 csv 파일에 어떤 dtypes가 있는지 추측하려고 시도합니다. 이것은 dtype을 결정하는 동안 모든 원시 데이터를 메모리에 객체 (문자열)로 유지해야하기 때문에 매우 무거운 작업입니다.

csv가 다음과 같다고 가정 해 보겠습니다.

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01

이 예제는 물론 메모리로 읽는 데 문제가 없지만 단지 예제 일뿐입니다.

pandas가 dtype 옵션 없이 위의 csv 파일을 읽으려면 pandas가 정규화 된 추측을하기에 충분한 csv 파일 행을 읽을 때까지 메모리에 문자열로 나이가 저장됩니다.

pandas의 기본값은 dtype을 추측하기 전에 1,000,000 개의 행을 읽는 것입니다.

해결책

dtype={'age':int}대한 옵션으로 지정 하면 .read_csv()팬더에게 나이가 숫자로 해석되어야 함을 알 수 있습니다. 이것은 당신에게 많은 메모리를 절약합니다.

손상된 데이터 문제

그러나 csv 파일이 손상되면 다음과 같이됩니다.

name, age, birthday
Alice, 30, 1985-01-01
Bob, 35, 1980-01-01
Charlie, 25, 1990-01-01
Dennis, 40+, None-Ur-Bz

그런 다음 지정 dtype={'age':int}하면 int로 .read_csv()캐스트 할 수 없기 때문에 명령 이 중단됩니다 "40+". 따라서 데이터를 신중하게 삭제하십시오!

여기에서는 float가 문자열로 유지 될 때 pandas 데이터 프레임의 메모리 사용량이 훨씬 더 높은 것을 확인할 수 있습니다.

직접 시도

df = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 224544 (~224 MB)

df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
# 79560 (~79 MB)


답변

약 1GB 크기 (550 만 개 이상의 레코드)로 탭으로 구분 된 텍스트 파일을 간단하게 읽을 때 동일한 메모리 문제가 발생하여 메모리 문제가 해결되었습니다.

df = pd.read_csv(myfile,sep='\t') # didn't work, memory error
df = pd.read_csv(myfile,sep='\t',low_memory=False) # worked fine and in less than 30 seconds

Spyder 3.2.3 Python 2.7.13 64 비트


답변

내 Linux 상자에서 Pandas를 사용하고 Pandas를 github에서 복제 한 후 최신 버전으로 업그레이드 한 후에 만 ​​해결 된 많은 메모리 누수에 직면했습니다.


답변

가상 머신에서 실행 중이거나 메모리가 엄청나게 제한된 다른 곳에서도이 문제가 발생했습니다. pandas, numpy 또는 csv와는 아무런 관련이 없지만, 파이썬뿐만 아니라 사용 권한에 따라 더 많은 메모리를 사용하려고하면 항상 발생합니다.

당신이 가진 유일한 기회는 당신이 이미 시도한 것입니다. 큰 것을 기억에 맞는 작은 조각으로 자르십시오.

MapReduce가 무엇인지 스스로 물어 본 적이 있다면 스스로 알아 냈습니다 … MapReduce는 많은 컴퓨터에 청크를 배포하려고 시도하고, 한 컴퓨터에서 차례로 청크를 처리하려고합니다.

청크 파일을 연결하여 찾은 내용은 실제로 문제가 될 수 있습니다.이 작업에 필요한 복사본이있을 수 있지만 결국 이것은 현재 상황에서 당신을 구할 수 있지만 csv가 조금 커지면 다시 그 벽에 부딪 힐 수 있습니다 …

또한 팬더가 너무 똑똑해서 큰 df에 연결하는 것과 같은 작업을 수행하면 실제로 개별 데이터 청크 만 메모리에로드 할 수 있습니다.

시도 할 수있는 몇 가지 방법 :

  • 한 번에 모든 데이터를로드하지 않고 조각으로 분할
  • 내가 아는 한, hdf5는 이러한 청크를 자동으로 수행 할 수 있으며 현재 프로그램이 작동하는 부분 만로드합니다.
  • 유형이 정상인지 확인하십시오. 문자열 ‘0.111111’은 부동 소수점보다 더 많은 메모리를 필요로합니다.
  • 실제로 필요한 것은 주소가 문자열로 있으면 수치 분석에 필요하지 않을 수도 있습니다.
  • 데이터베이스는 실제로 필요한 부분 만 액세스하고로드하는 데 도움이 될 수 있습니다 (예 : 활성 사용자 1 % 만)


답변

Pandas 0.12.0 및 NumPy 1.8.0에는 오류가 없습니다.

큰 DataFrame을 만들고 csv 파일에 저장 한 다음 성공적으로 읽었습니다. 여기 에서 예를 참조 하십시오 . 파일 크기는 554Mb입니다 (1.1Gb 파일에서도 작동했지만 1.1Gb 파일 사용 빈도를 30 초로 생성하는 데 더 오래 걸렸습니다). 4Gb의 RAM을 사용할 수 있지만.

내 제안은 Pandas를 업데이트하는 것입니다. 유용한 다른 것은 R의 경우 Visual Studio를 사용하지 않기 때문에 (이미 질문에 대한 의견에서 제 안됨) 더 많은 리소스를 사용할 수 있기 때문에 명령 줄에서 스크립트를 실행하는 것입니다.


답변

chunksize큰 CSV 파일을 읽으면서 시도 했습니다.

reader = pd.read_csv(filePath,chunksize=1000000,low_memory=False,header=0)

이제 읽기가 목록입니다. 우리는 reader새 csv를 반복 하고 쓰거나 추가하거나 어떤 작업을 수행 할 수 있습니다.

for chunk in reader:
    print(newChunk.columns)
    print("Chunk -> File process")
    with open(destination, 'a') as f:
        newChunk.to_csv(f, header=False,sep='\t',index=False)
        print("Chunk appended to the file")


답변

추가 : ratings = pd.read_csv (…, low_memory = False, memory_map = True )

이 두 가지에 대한 내 기억 : # 319.082.496이 두 가지없이 : # 349.110.272