Python 2와 3 사이의 numpy 배열의 피클 비 호환성


163

이 프로그램을 사용하여 Python 3.2에서 여기 에 링크 된 MNIST 데이터 세트를로드하려고합니다 .

import pickle
import gzip
import numpy


with gzip.open('mnist.pkl.gz', 'rb') as f:
    l = list(pickle.load(f))
    print(l)

불행히도 오류가 발생합니다.

Traceback (most recent call last):
   File "mnist.py", line 7, in <module>
     train_set, valid_set, test_set = pickle.load(f)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)

그런 다음 Python 2.7에서 절인 파일을 디코딩하고 다시 인코딩하려고했습니다. 그래서 파이썬 2.7 에서이 프로그램을 실행했습니다.

import pickle
import gzip
import numpy


with gzip.open('mnist.pkl.gz', 'rb') as f:
    train_set, valid_set, test_set = pickle.load(f)

    # Printing out the three objects reveals that they are
    # all pairs containing numpy arrays.

    with gzip.open('mnistx.pkl.gz', 'wb') as g:
        pickle.dump(
            (train_set, valid_set, test_set),
            g,
            protocol=2)  # I also tried protocol 0.

오류없이 실행되었으므로 Python 3.2 에서이 프로그램을 다시 실행했습니다.

import pickle
import gzip
import numpy

# note the filename change
with gzip.open('mnistx.pkl.gz', 'rb') as f:
    l = list(pickle.load(f))
    print(l)

그러나 이전과 같은 오류가 발생했습니다. 이것을 작동 시키려면 어떻게해야합니까?


이는 MNIST 데이터 세트를로드하는 데 더 나은 방법입니다.


2.7과 3.x 사이의 호환성 중단이 있습니다. 특히 문자열 대 유니 코드. 그리고 numpy 객체를 선택하려면 두 시스템 모두 numpy 모듈을로드해야하지만 해당 모듈은 다릅니다. 죄송합니다. 답변이 없지만 가능하지 않을 수 있으며 아마도 권장하지 않습니다. 이것이 큰 일 (gzip)이라면 아마도 pytables가있는 hdf5입니까?
Phil Cooper

@ PhilCooper : 감사합니다. 귀하의 의견 (이 답변으로 게시 하시겠습니까?)이 정답에 나를 붙였습니다. 나는 hdf5를 사용할 수 있었지만 배우기가 복잡해 보였으므로 numpy.save/load를 사용하여 작동했습니다.
Neil G

h5py는 사용하기가 매우 간단하며, numpy 배열을 산세하는 것과의 호환성 문제를 해결하는 것이 훨씬 쉽습니다.
DaveP

"Python 2.7에서이 프로그램을 실행했습니다"라고 말합니다. OK. 그러나 3.2에서 무엇을 했습니까? :-) 똑같다?
Lennart Regebro

@LennartRegebro : 배열을 피클하는 두 번째 프로그램을 실행 한 후 Python 3.2에서 첫 번째 프로그램 (파일 이름 mnistx.pkl.gz로 대체)을 실행했습니다. 작동하지 않아서 비 호환성을 나타냅니다.
Neil G

답변:


141

이것은 일종의 비 호환성처럼 보입니다. ASCII로 간주되는 "binstring"오브젝트를로드하려고 시도하는 중이지만이 경우에는 이진 데이터입니다. 이것이 Python 3 unpickler의 버그이거나 numpy에 의한 pickler의 "오용"이라면 모르겠습니다.

여기에 해결 방법이 있지만이 시점에서 데이터가 얼마나 의미가 있는지 모르겠습니다.

import pickle
import gzip
import numpy

with open('mnist.pkl', 'rb') as f:
    u = pickle._Unpickler(f)
    u.encoding = 'latin1'
    p = u.load()
    print(p)

Python 2에서 피클 링을 해제 한 다음 다시 피클 링하면 동일한 문제가 다시 생성되므로 다른 형식으로 저장해야합니다.


211
사용할 수 있습니다 pickle.load(file_obj, encoding='latin1')(적어도 Python 3.3에서는). 이것은 작동하는 것 같습니다 .
Tom Aldcroft

7
numpy load를 사용하고 비슷한 문제에 직면 한 사람들을 위해 : 인코딩도 전달할 수 있습니다 :np.load('./bvlc_alexnet.npy', encoding='latin1')
Serj Zaharchenko

추가에 encoding='latin1'실패 했을 때 도움이되었습니다 . 감사!
Guillem Cucurull 2016 년

130

당신은 python3에서이 오류가 발생하는 경우, 그것은 파이썬 2와 파이썬 3 사이의 호환성 문제 일 수 있습니다, 나를 위해 솔루션이었다 loadlatin1인코딩 :

pickle.load(file, encoding='latin1')

16

파이썬 2와 파이썬 3 사이의 비 호환성 문제인 것 같습니다. MNIST 데이터 셋을로드하려고했습니다.

    train_set, valid_set, test_set = pickle.load(file, encoding='iso-8859-1')

파이썬 3.5.2에서 작동했습니다.


7

유니 코드로의 이동으로 인해 2.x와 3.x 사이에서 피클에 일부 호환성 문제가있는 것 같습니다 . 파일이 python 2.x로 절인 것처럼 보이며 3.x로 디코딩하면 문제가 될 수 있습니다.

python 2.x로 선택을 풀고 사용중인 두 버전에서 더 잘 재생되는 형식으로 저장하는 것이 좋습니다.


2
그것이 내가하려고했던 것입니다. 어떤 형식을 권장하십니까?
Neil G

5
문제가 numpy dtype을 인코딩 한 것일 수 있습니다. 이것은 문자열 일 수 있습니다. 어쨌든 파이썬 2와 3 사이의 간격을 메우기 위해 numpy.save/load를 사용하여 결과가 나왔습니다.
Neil G

7

나는이 발췌 문장을 우연히 발견했다. 이것이 호환성 문제를 분명히하는 데 도움이되기를 바랍니다.

import sys

with gzip.open('mnist.pkl.gz', 'rb') as f:
    if sys.version_info.major > 2:
        train_set, valid_set, test_set = pickle.load(f, encoding='latin1')
    else:
        train_set, valid_set, test_set = pickle.load(f)

증폭 정보를 더 추가해보십시오. 이것이 어떻게 문제를 해결합니까?
Tom Aranda

@serge 대답에 그 도움을주세요 설명
Sarath Sadasivan 필라

6

시험:

l = list(pickle.load(f, encoding='bytes')) #if you are loading image data or 
l = list(pickle.load(f, encoding='latin1')) #if you are loading text data

pickle.load방법 의 문서에서 :

선택적 키워드 인수는 fix_imports, encoding 및 errors이며, Python 2에서 생성 된 피클 스트림에 대한 호환성 지원을 제어하는 ​​데 사용됩니다.

fix_imports가 True 인 경우 pickle은 이전 Python 2 이름을 Python 3에서 사용 된 새 이름으로 매핑하려고 시도합니다.

인코딩과 오류는 피클에게 파이썬 2에 의해 선택된 8 비트 문자열 인스턴스를 디코딩하는 방법을 알려줍니다. 이들은 각각 'ASCII'및 'strict'로 설정됩니다. 이 8 비트 문자열 인스턴스를 바이트 객체로 읽는 인코딩은 '바이트'일 수 있습니다.


0

피클보다 빠르고 더 쉬운 방해가 있습니다. 나는 피클 덤프로 저장하고 읽으려고했지만 읽는 동안 많은 문제가 있었고 한 시간을 낭비했지만 챗봇을 만들기 위해 자체 데이터로 작업하고 있지만 해결책을 찾지 못했습니다.

vec_xvec_yNumPy와 배열은 다음과 같습니다 :

data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )

그런 다음 그냥 읽고 작업을 수행하십시오.

data2 = hkl.load( 'new_data_file.hkl' )
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.