Numpy.array () verileri nasıl düzgün şekilde kaydedilir ve yüklenir?


108

numpy.arrayVerilerin nasıl düzgün şekilde kaydedilip yükleneceğini merak ediyorum . Şu anda numpy.savetxt()yöntemi kullanıyorum . Örneğin, markersşuna benzeyen bir dizim varsa :

görüntü açıklamasını buraya girin

Şunu kullanarak onu kurtarmaya çalışıyorum:

numpy.savetxt('markers.txt', markers)

Diğer komut dosyasında önceden kaydedilmiş dosyayı açmaya çalışıyorum:

markers = np.fromfile("markers.txt")

Ve bunu anlıyorum ...

görüntü açıklamasını buraya girin

Kaydedilen veriler ilk olarak şuna benzer:

0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00

Ama aynı yöntemi kullanarak yüklenen veriyi kaydettiğimde, yani. numpy.savetxt()şuna benziyor:

1.398043286095131769e-76
1.398043286095288860e-76
1.396426376485745879e-76
1.398043286055061908e-76
1.398043286095288860e-76
1.182950697433698368e-76
1.398043275797188953e-76
1.398043286095288860e-76
1.210894289234927752e-99
1.398040649781712473e-76

Neyi yanlış yapıyorum? Not: Yaptığım başka bir "sahne arkası" işlemi yok. Sadece kaydetme ve yükleme, ve bunu elde ediyorum. Şimdiden teşekkür ederim.


Metin dosyasının çıktısı nedir? Neden bir CSV dosyasına yazmıyorsunuz?

5
İnsan tarafından okunabilir metin dosyaları olarak kaydetmeniz ve yüklemeniz mi gerekiyor? Daha hızlı olacaktır (ve dosyalar daha kompakt olacaktır) kaydetmek eğer / kullanarak ikili dosyaları yüklemek np.save()ve np.load().
ali_m

Tavsiyen için teşekkürler. Yardımcı oldu. Bununla birlikte, neden ne olduğunu ve verileri * .txt formatında kaydetmeye ve baş ağrısız yüklemeye izin vermenin bir yolu olup olmadığını açıklayabilir misiniz? Örneğin, matlab, java veya diğer araçlar / diller ile çalışmak istendiğinde.
bluevoxel

3
MATLAB'a / MATLAB'dan dizileri geçirmek için scipy.io.savematve kullanabilirsiniz scipy.io.loadmat.
ali_m

2
Varsayılan değer fromfile, verileri ikili olarak okumaktır. loadtxtile doğru eşleştirmedir savetxt. İşlev belgelerine bakın.
hpaulj

Yanıtlar:


153

Bunu yapmanın bulduğum en güvenilir yolu, np.savetxtbirlikte yazılan ikili dosyalar için daha uygun olanı np.loadtxtdeğil , kullanmaktır . Ve yöntemler yazmak ve oysa ikili dosyaları okumak bir metin dosyası yazar. Yani mesela:np.fromfiletofilenp.fromfilenp.tofilenp.savetxt

a = np.array([1, 2, 3, 4])
np.savetxt('test1.txt', a, fmt='%d')
b = np.loadtxt('test1.txt', dtype=int)
a == b
# array([ True,  True,  True,  True], dtype=bool)

Veya:

a.tofile('test2.dat')
c = np.fromfile('test2.dat', dtype=int)
c == a
# array([ True,  True,  True,  True], dtype=bool)

Daha yavaş olsa ve daha büyük dosyalar oluştursa bile eski yöntemi kullanıyorum (bazen): ikili format platforma bağlı olabilir (örneğin, dosya formatı sisteminizin dayanıklılığına bağlıdır).

Bir yoktur platform bağımsız kaydedilir ve okunabilir NumPy diziler, biçimi np.saveve np.load:

np.save('test3.npy', a)    # .npy extension is added if not given
d = np.load('test3.npy')
a == d
# array([ True,  True,  True,  True], dtype=bool)

49
.npy(tarafından oluşturulan örn dosyaları np.save()) vardır platformdan bağımsız ve daha kompakt olacak ve daha hızlı metin dosyaları daha oluşturun.
ali_m

2
ayrıca np.savezçıktının sıkıştırılmasını istiyorsanız.
tegan

3
@tegan np.savezbirkaç diziyi sıkıştırılmamış olarak kaydeder - np.savez_compressedonları sıkıştırır - henüz np.save_compressedyok. Docs.scipy.org/doc/numpy-1.15.1/reference/routines.io.html adresine
Brian Burns

1
Teşekkürler xnx Aynı sorunu yaşıyordum (dtype float ile) np.savetxt ile np.loadtxt kullanarak bunu çözdüm
Yogesh

2 GB'tan büyük turşu kaydetme konusunda sorun yaşadım. Xnx sayesinde sorun a.tofile ve np.fromfile kullanılarak çözüldü.
Azr

51
np.save('data.npy', num_arr) # save
new_num_arr = np.load('data.npy') # load

3

np.fromfile()bir sep=anahtar kelime bağımsız değişkenine sahiptir:

Dosya bir metin dosyasıysa öğeler arasında ayırıcı. Boş ("") ayırıcı, dosyanın ikili olarak işlem görmesi gerektiği anlamına gelir. Ayırıcıdaki boşluklar (””) sıfır veya daha fazla boşluk karakteriyle eşleşir. Yalnızca boşluklardan oluşan bir ayırıcı, en az bir boşlukla eşleşmelidir.

Varsayılan değeri, onu boşlukla ayrılmış metin dosyası yerine ikili dosya olarak okumaya çalışan sep=""anlamına gelir np.fromfile(), böylece anlamsız değerleri geri alırsınız. Eğer kullanırsanız np.fromfile('markers.txt', sep=" "), aradığınız sonucu alırsınız.

Bununla birlikte, diğerlerinin de belirttiği gibi, np.loadtxt()metin dosyalarını uyuşmuş dizilere dönüştürmenin tercih edilen yolu budur ve dosyanın insan tarafından okunabilir olması gerekmedikçe, bunun yerine ikili biçimleri kullanmak genellikle daha iyidir (örneğin np.load()/ np.save()).


1

Kısa bir cevap için np.saveve kullanmalısınız np.load. Bunların avantajları, numpy kitaplığının geliştiricileri tarafından yapılmış olmaları ve halihazırda çalışıyor olmalarıdır (artı muhtemelen zaten güzel bir şekilde optimize edilmiştir) örn.

import numpy as np
from pathlib import Path

path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)

lb,ub = -1,1
num_samples = 5
x = np.random.uniform(low=lb,high=ub,size=(1,num_samples))
y = x**2 + x + 2

np.save(path/'x', x)
np.save(path/'y', y)

x_loaded = np.load(path/'x.npy')
y_load = np.load(path/'y.npy')

print(x is x_loaded) # False
print(x == x_loaded) # [[ True  True  True  True  True]]

Genişletilmiş cevap:

Sonunda, gerçekten ihtiyaçlarınıza bağlıdır çünkü onu insan tarafından okunabilir formatta kaydedebilirsiniz (bu NumPy dizisini bir csv dosyasına dökmeye bakın ) veya dosyalarınız çok büyükse diğer kitaplıklarla bile ( uyuşmuş dizileri korumanın en iyi yolunu görün) genişletilmiş bir tartışma için diskte ).

Bununla birlikte, (sorunuzda "doğru" kelimesini kullandığınız için bir genişletme yapmak) Hala kutudan çıkan numpy işlevini (ve çoğu kodu!) Kullanmanın çoğu kullanıcı ihtiyacını karşılayacağını düşünüyorum. En önemli nedeni zaten çalışıyor olmasıdır . Başka bir nedenle başka bir şeyi kullanmaya çalışmak, neden çalışmadığını anlamak ve işe yaramaya zorlamak için sizi beklenmedik bir UZUN tavşan deliğine götürebilir.

Örneğin turşu ile kurtarmaya çalışın. Bunu sadece eğlence için denedim ve dosyayı bayt modunda açıp okumadıkça turşunun eşyalarımı kurtarmayacağını anlamam en az 30 dakikamı aldı wb. Google'a zaman ayırdı, bir şeyi dene, hata mesajını anla vs ... Küçük detay ama zaten bir dosyayı açmamı gerektirmesi, işleri beklenmedik şekillerde karmaşık hale getirdi. Bunu yeniden okumamı gerektirdiğini eklemek için (hangi btw biraz kafa karıştırıcıdır) Yerleşik açık işlevde a, a +, w, w + ve r + modları arasındaki fark? .

Öyleyse, ihtiyaçlarınızı karşılayan bir arabirim varsa, ( çok ) iyi bir nedeniniz yoksa (örneğin, matlab ile uyumluluk veya herhangi bir nedenle dosyayı gerçekten okumak ve python'da yazdırmak gerçekten ihtiyaçlarınızı karşılamıyorsa) kullanın. şüpheli olabilir). Ayrıca, büyük olasılıkla optimize etmeniz gerekirse, daha sonra öğreneceksiniz (basit bir numpy dosyası açmak gibi gereksiz şeylerde hata ayıklamak için zaman harcamak yerine).

Bu yüzden / numpy sağlama arayüzünü kullanın . Mükemmel olmayabilir, büyük olasılıkla iyidir, özellikle de uzun süredir ortalıkta olmayan bir kütüphane için.

Verileri kaydetme ve yükleme işini numpy ile bir sürü şekilde harcadım, bu yüzden eğlenin, umarım yardımcı olur!

import numpy as np
import pickle
from pathlib import Path

path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)

lb,ub = -1,1
num_samples = 5
x = np.random.uniform(low=lb,high=ub,size=(1,num_samples))
y = x**2 + x + 2

# using save (to npy), savez (to npz)
np.save(path/'x', x)
np.save(path/'y', y)
np.savez(path/'db', x=x, y=y)
with open(path/'db.pkl', 'wb') as db_file:
    pickle.dump(obj={'x':x, 'y':y}, file=db_file)

## using loading npy, npz files
x_loaded = np.load(path/'x.npy')
y_load = np.load(path/'y.npy')
db = np.load(path/'db.npz')
with open(path/'db.pkl', 'rb') as db_file:
    db_pkl = pickle.load(db_file)

print(x is x_loaded)
print(x == x_loaded)
print(x == db['x'])
print(x == db_pkl['x'])
print('done')

Öğrendiklerime dair bazı yorumlar:

  • np.savebeklendiği gibi, bu zaten onu iyi sıkıştırır (bkz. https://stackoverflow.com/a/55750128/1601580 ), herhangi bir dosya açılmadan kutudan çıkar. Temiz. Kolay. Verimli. Kullan onu.
  • np.savezsıkıştırılmamış bir biçim kullanır (bkz. belgeler ) Save several arrays into a single file in uncompressed .npz format.Bunu kullanmaya karar verirseniz (standart çözümden uzaklaşmanız için uyarıldınız, bu nedenle hatalar bekleyin !), istemediğiniz sürece, bağımsız değişken adlarını kullanmanız gerektiğini keşfedebilirsiniz. varsayılan isimleri kullanın. Bu nedenle, ilk zaten çalışıyorsa bunu kullanmayın (veya herhangi bir çalışma bunu kullanır!)
  • Turşu ayrıca isteğe bağlı kod yürütülmesine izin verir. Bazı insanlar güvenlik nedeniyle bunu kullanmak istemeyebilir.
  • insanlar tarafından okunabilir dosyaların oluşturulması pahalıdır, vb. Muhtemelen buna değmez.
  • hdf5büyük dosyalar için çağrılan bir şey var . Güzel! https://stackoverflow.com/a/9619713/1601580

Bunun kapsamlı bir cevap olmadığını unutmayın. Ancak diğer kaynaklar için şunu kontrol edin:

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.