Python 2 ve 3 arasındaki numpy dizilerinin turşu uyumsuzluğu


163

Bu programı kullanarak burada Python 3.2 bağlı MNIST veri kümesini yüklemeye çalışıyorum :

import pickle
import gzip
import numpy


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

Ne yazık ki, bana hata veriyor:

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)

Daha sonra Python 2.7'de turşu dosyasını çözmeyi ve yeniden kodlamayı denedim. Bu programı Python 2.7'de çalıştırdım:

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.

Hatasız koştu, bu yüzden Python 3.2 bu programı yeniden:

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)

Ancak, bana önceki hata ile aynı hatayı verdi. Bunu nasıl çalıştırabilirim?


Bu, MNIST veri kümesini yüklemek için daha iyi bir yaklaşımdır.


2.7 ile 3.x arasında uyumluluk kopmaları var. özellikle string vs unicode. Ve bir numpy nesnesi seçmek, her iki sistemin numpy modülünü yüklemesini gerektirir, ancak bu modüller farklıdır. Üzgünüm bir cevabım yok ama bu mümkün olmayabilir ve muhtemelen tavsiye edilmez. Bu büyük şeyler (gzip) ise, belki ptables ile hdf5 ??
Phil Cooper

@PhilCooper: Teşekkürler, yorumunuz (bunu bir cevap olarak gönderin?) Beni doğru cevaba aktardı. Hdf5'i kullanabilirdim, ama öğrenmek karmaşık görünüyordu, bu yüzden numpy.save/load ile gittim ve bu işe yaradı.
Neil G

h5py kullanımı çok basittir, nümerik dizilerle dekapaj problemlerini çözdükten sonra kesinlikle çok daha kolaydır.
DaveP

"Bu programı Python 2.7 altında çalıştırdınız" diyorsunuz. Tamam ama 3.2 altında ne yaptınız? :-) Aynısı?
Lennart Regebro

@LennartRegebro: Dizileri toplayan ikinci programı çalıştırdıktan sonra, Python 3.2'deki ilk programı (mnistx.pkl.gz dosya adını kullanarak) çalıştırdım. İşe yaramadı, bence bir tür uyumsuzluğu gösteriyor.
Neil G

Yanıtlar:


141

Bu bir tür uyumsuzluk gibi görünüyor. ASCII olduğu varsayılan bir "binstring" nesnesini yüklemeye çalışıyor, bu durumda ikili veri. Bu Python 3 unpickler bir hata veya numpy tarafından pickler bir "kötüye", bilmiyorum.

İşte bir geçici çözüm, ama verilerin bu noktada ne kadar anlamlı olduğunu bilmiyorum:

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'de seçimini kaldırmak ve daha sonra tekrarlamak aynı sorunu tekrar yaratacaktır, bu yüzden başka bir biçimde kaydetmeniz gerekir.


211
Kullanabilirsiniz pickle.load(file_obj, encoding='latin1')(en azından Python 3.3'te). Bu işe yarıyor gibi görünüyor .
Tom Aldcroft

7
Numpy yükü kullananlar ve benzer bir sorunla karşı karşıya olanlar için: orada kodlamayı da geçmek mümkündür:np.load('./bvlc_alexnet.npy', encoding='latin1')
Serj Zaharchenko

Ekleme encoding='latin1'başarısız olduğunda bu benim için çalıştı . Teşekkürler!
Guillem Cucurull

130

Eğer python3 bu hatayı alıyorsanız, o zaman, piton 2 ve piton 3 arasında bir uyumsuzluk sorunu olabilir, benim için bir çözüm oldu loadile latin1kodlama:

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

16

Python 2 ve Python 3 arasında bir uyumsuzluk sorunu olduğu anlaşılıyor. MNIST veri kümesini

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

ve Python 3.5.2 için çalıştı


7

Unicode'a geçiş nedeniyle turşuda 2.x ve 3.x arasında bazı uyumluluk sorunları var gibi görünüyor . Dosyanız python 2.x ile turşu gibi görünüyor ve 3.x içinde kodunu çözmek zahmetli olabilir.

Bunu python 2.x ile seçmeyi ve kullandığınız iki sürüm arasında daha güzel oynayan bir formata kaydetmenizi öneririm.


2
Ben de bunu yapmaya çalışıyordum. Hangi biçimi öneriyorsunuz?
Neil G

5
Sorun bir dize olabilir numpy dtype kodlama olabilir düşünüyorum. Her halükarda, python 2 ve 3 arasındaki boşluğu kapatmak için numpy.save/load kullandım ve bu işe yaradı.
Neil G

7

Ben sadece bu pasajı tökezledim. Umarım bu uyumluluk sorununu açıklığa kavuşturur.

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)

Daha fazla güçlendirici bilgi eklemeyi düşünün. Bu sorunu nasıl çözer?
Tom Aranda

@serge yardımcı oldu, lütfen cevaba açıklama
Sarath Sadasivan Pillai

6

Deneyin:

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.loadYöntemin dokümantasyonundan :

İsteğe bağlı anahtar kelime bağımsız değişkenleri, Python 2 tarafından oluşturulan turşu akışı için uyumluluk desteğini denetlemek için kullanılan fix_imports, kodlama ve hatalardır.

Fix_imports Doğru ise, turşu eski Python 2 adlarını Python 3'te kullanılan yeni adlarla eşlemeye çalışır.

Kodlama ve hatalar, turşuya Python 2 tarafından 8 bitlik dize örneklerinin kodunun nasıl çözüleceğini söyler; bunlar varsayılan olarak sırasıyla 'ASCII' ve 'katı' şeklindedir. Bu 8 bit dize örneklerini bayt nesneleri olarak okumak için kodlama 'bayt' olabilir.


0

Turşudan daha hızlı ve daha kolay bir hickle var. Turşu dökümünde kaydetmeye ve okumaya çalıştım ama okurken çok fazla sorun vardı ve bir saat harcadım ve bir chatbot oluşturmak için kendi verilerim üzerinde çalışmama rağmen hala bir çözüm bulamadım.

vec_xve vec_ynumpy dizileridir:

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

Sonra sadece okuyun ve işlemleri gerçekleştirin:

data2 = hkl.load( 'new_data_file.hkl' )
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.