Numpy.array (डेटा) को ठीक से कैसे सहेजना और लोड करना है?


103

मुझे आश्चर्य है, कैसे numpy.arrayठीक से डेटा को बचाने और लोड करने के लिए । वर्तमान में मैं numpy.savetxt()विधि का उपयोग कर रहा हूं । उदाहरण के लिए, अगर मुझे एक सरणी मिली markers, जो इस तरह दिखती है:

यहां छवि विवरण दर्ज करें

मैं इसके इस्तेमाल से बचाने की कोशिश करता हूं:

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

अन्य स्क्रिप्ट में मैं पहले से सहेजी गई फ़ाइल को खोलने का प्रयास करता हूं:

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

और यही मुझे मिलता है ...

यहां छवि विवरण दर्ज करें

सहेजा गया डेटा पहले इस तरह दिखता है:

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

लेकिन जब मैं एक ही विधि के उपयोग से केवल लोड किए गए डेटा को बचाता हूं, अर्थात। numpy.savetxt()यह इस तरह दिख रहा है:

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

मैं क्या गलत कर रहा हूं? PS कोई अन्य "बैकस्टेज" ऑपरेशन नहीं है जो मैं करता हूं। बस बचत और लोडिंग, और यही मुझे मिलता है। पहले ही, आपका बहुत धन्यवाद।


टेक्स्ट फ़ाइल का आउटपुट क्या है? सिर्फ CSV फ़ाइल में क्यों नहीं लिखें?

4
क्या आपको मानव-पढ़ने योग्य पाठ फ़ाइलों के रूप में सहेजने और लोड करने की आवश्यकता है? यदि आप बाइनरी फ़ाइलों का उपयोग करके np.save()और लोड करते हैं तो यह तेज़ हो जाएगा (और फ़ाइलें अधिक कॉम्पैक्ट होंगी) np.load()
एलिअम

आपकी सलाह के लिए धन्यवाद। यह मदद करता है। हालांकि, क्या आप बता सकते हैं कि यह क्यों है, और यदि * .txt प्रारूप में डेटा सहेजने और सिरदर्द के बिना लोड करने की अनुमति देने का कोई तरीका है? उदाहरण के लिए, जब कोई मटलब, जावा या अन्य उपकरण / भाषाओं के साथ काम करना चाहता है।
ब्लूवॉक्सेल

3
MATLAB से / के लिए सरणियों को पास करने के लिए आप उपयोग कर सकते हैं scipy.io.savematऔर scipy.io.loadmat
अली_म

2
डिफ़ॉल्ट के लिए fromfileडेटा को बाइनरी के रूप में पढ़ना है। loadtxtके साथ सही बाँधना है savetxt। फ़ंक्शन दस्तावेज़ देखें।
hpaulj

जवाबों:


144

ऐसा करने के लिए मैंने जो सबसे विश्वसनीय तरीका खोजा है, वह है इसके np.savetxtसाथ प्रयोग करना np.loadtxtऔर न np.fromfileकि जो कि लिखी गई बाइनरी फाइलों के लिए बेहतर है tofilenp.fromfileऔर np.tofileतरीकों लिख सकते हैं और जबकि द्विआधारी फ़ाइलों को पढ़ने के np.savetxtएक पाठ फ़ाइल लिखता है। इसलिए, उदाहरण के लिए:

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

या:

In [5]: a.tofile('test2.dat')
In [6]: c = np.fromfile('test2.dat', dtype=int)
In [7]: c == a
Out[7]: array([ True,  True,  True,  True], dtype=bool)

मैं पूर्व विधि का उपयोग करता हूं भले ही यह धीमा हो और बड़ी फाइलें बनाता है (कभी-कभी): द्विआधारी प्रारूप मंच पर निर्भर हो सकता है (उदाहरण के लिए, फ़ाइल प्रारूप आपके सिस्टम की समाप्ति पर निर्भर करता है)।

वहाँ एक है मंच स्वतंत्र NumPy सरणी, जो बचाया जा सकता है और पढ़ने के साथ के लिए प्रारूप np.saveऔर np.load:

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

46
.npyफ़ाइलें (जैसे द्वारा उत्पन्न np.save()) कर रहे हैं मंच स्वतंत्र है, और अधिक कॉम्पैक्ट हो जाएगा और तेजी से पाठ फ़ाइलों से बनाने के लिए।
एलिअम_

2
भी np.savezआप उत्पादन संकुचित चाहते हैं।
टेगन

3
@tegan np.savezकई सरणियों को असम्पीडित बचाता है - np.savez_compressedउन्हें संपीड़ित करेगा - np.save_compressedअभी तक नहीं है। Docs.scipy.org/doc/numpy-1.15.1/reference/routines.io.html
ब्रायन बर्न्स

1
धन्यवाद xnx मैं एक ही मुद्दा (dtype फ्लोट के साथ) np.savetxt का उपयोग कर रहा था np.loadtxt के साथ इसे हल किया
योगेश

मेरे पास 2GB से अधिक अचार बचत डेटा के साथ समस्या थी। A.tofile और np.fromfile का उपयोग करके समस्या को हल करने के लिए xnx का धन्यवाद।
अज़हर हुसैन


3

np.fromfile()एक sep=खोजशब्द तर्क है:

यदि फ़ाइल एक पाठ फ़ाइल है तो आइटम के बीच विभाजक। खाली ("") विभाजक का अर्थ है कि फ़ाइल को द्विआधारी के रूप में माना जाना चाहिए। विभाजक में रिक्त स्थान ("") शून्य या अधिक व्हाट्सएप वर्णों से मेल खाते हैं। केवल एक रिक्त स्थान से युक्त विभाजक को कम से कम एक व्हाट्सएप से मेल खाना चाहिए।

डिफ़ॉल्ट मान का sep=""अर्थ है कि np.fromfile()यह एक अलग-अलग पाठ फ़ाइल के बजाय एक बाइनरी फ़ाइल के रूप में पढ़ने की कोशिश करता है, इसलिए आपको बकवास मान वापस मिल जाते हैं। यदि आप उपयोग करते np.fromfile('markers.txt', sep=" ")हैं तो आपको वह परिणाम मिलेगा जिसकी आपको तलाश है।

हालाँकि, जैसा कि अन्य ने बताया है, np.loadtxt()पाठ फ़ाइलों को सुपीरियर सरणियों में बदलने का पसंदीदा तरीका है, और जब तक फ़ाइल को मानव-पठनीय होने की आवश्यकता नहीं होती है तब तक इसके बजाय बाइनरी प्रारूपों का उपयोग करना बेहतर होता है (जैसे np.load()/ np.save())।


उपयोग करने के साथ कोई समस्या है pickle?
चार्ली पार्कर

0

एक छोटे से उत्तर के लिए आपको उपयोग करना चाहिए np.saveऔर np.load। इनका लाभ यह है कि वे सुपी लाइब्रेरी के डेवलपर्स द्वारा बनाए जाते हैं और वे पहले से ही काम करते हैं (प्लस संभवतः पहले से ही अच्छी तरह से अनुकूलित हैं आदि)

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]]

विस्तारित उत्तर:

अंत में यह वास्तव में आपकी आवश्यकताओं पर निर्भर करता है क्योंकि आप इसे मानव पठनीय प्रारूप भी सहेज सकते हैं (इस डम्प को एक Numvy सरणी को एक csv फ़ाइल में देखें ) या अन्य पुस्तकालयों के साथ भी अगर आपकी फाइलें बहुत बड़ी हैं ( संख्यात्मक सारणी को संरक्षित करने का यह सबसे अच्छा तरीका देखें) डिस्क पर एक विस्तारित चर्चा के लिए )।

हालांकि, जब से आप अपने प्रश्न में "ठीक से" शब्द का उपयोग करते हैं तब से एक विस्तार कर रहा है) मुझे अभी भी लगता है कि बॉक्स से बाहर और (सबसे कोड!) सबसे अधिक उपयोगकर्ता की जरूरतों को पूरा करता है। सबसे महत्वपूर्ण कारण यह है कि यह पहले से ही काम करता है । किसी अन्य कारण से किसी और चीज का उपयोग करने की कोशिश करना आपको अप्रत्याशित रूप से लंबे खरगोश छेद पर ले जा सकता है ताकि यह पता चले कि यह काम क्यों नहीं करता है और इसे काम करने के लिए मजबूर नहीं करता है।

उदाहरण के लिए अचार के साथ इसे बचाने की कोशिश करें। मैंने कोशिश की कि बस मज़े के लिए और मुझे यह महसूस करने में कम से कम 30 मिनट का समय लगे कि अचार मेरे सामान को तब तक नहीं बचाएगा जब तक कि मैंने फ़ाइल को बाइट्स मोड में नहीं खोला और पढ़ा wb। Google को समय दिया, चीज़ की कोशिश करें, त्रुटि संदेश आदि को समझें ... छोटा विवरण लेकिन यह तथ्य कि मुझे पहले से ही अप्रत्याशित तरीके से फ़ाइल जटिल चीजों को खोलने की आवश्यकता थी। यह जोड़ने के लिए कि मुझे इस (जो btw को भ्रमित करने की तरह है) को फिर से पढ़ने के लिए आवश्यक है , बिल्ट-इन ओपन फंक्शन में मोड ए, ए, डब्ल्यू, डब्ल्यू + और आर + के बीच अंतर।

इसलिए यदि कोई ऐसा इंटरफ़ेस है जो आपकी आवश्यकताओं को पूरा करता है, तो इसका उपयोग तब तक करें जब तक कि आपके पास एक बहुत ( बहुत अच्छा) कारण न हो (जैसे मैटलैब के साथ संगतता या किसी कारण से आपका वास्तव में फ़ाइल को पढ़ना और अजगर में मुद्रण करना वास्तव में आपकी आवश्यकताओं को पूरा नहीं करता है, जो संदिग्ध हो सकता है)। इसके अलावा, सबसे अधिक संभावना है कि अगर आपको इसे अनुकूलित करने की आवश्यकता है, तो आपको बाद में पता चलेगा कि लाइन के नीचे (खर्च करने की उम्र के बजाय एक साधारण खसखस ​​फ़ाइल खोलने की तरह बेकार सामान)।

इसलिए इंटरफ़ेस / सुन्न प्रदान का उपयोग करें । यह सही नहीं हो सकता है यह सबसे अधिक संभावना है ठीक है, विशेष रूप से एक पुस्तकालय के लिए जो लगभग लंबे समय तक सुन्न रहा है।

मैंने पहले से ही बचत और लोडिंग डेटा को एक गुच्छा के रूप में सुन्न के साथ बिताया है ताकि इसके साथ मज़ेदार हो, आशा है कि यह मदद करता है!

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')

मैंने जो कुछ सीखा उस पर कुछ टिप्पणियां:

  • np.saveजैसा कि अपेक्षित था, यह पहले से ही इसे अच्छी तरह से संपीड़ित करता है (देखें https://stackoverflow.com/a/55750128/1601580 ), बिना किसी फ़ाइल को खोले बॉक्स से बाहर काम करता है। स्वच्छ। आसान। कुशल। इसका इस्तेमाल करें।
  • np.savezएक असम्पीडित प्रारूप का उपयोग करता है ( डॉक्स देखें ) Save several arrays into a single file in uncompressed .npz format.यदि आप इसका उपयोग करने का निर्णय लेते हैं (आपको मानक समाधान से दूर जाने की चेतावनी दी गई थी, तो बग्स की अपेक्षा करें!) आपको पता चल सकता है कि आपको इसे बचाने के लिए तर्क नामों का उपयोग करने की आवश्यकता है, जब तक कि आप नहीं चाहते हैं। डिफ़ॉल्ट नामों का उपयोग करें। तो पहले से ही काम करता है (या किसी भी काम करता है कि इस का उपयोग न करें!)
  • अचार भी मनमाना कोड निष्पादन के लिए अनुमति देता है। कुछ लोग सुरक्षा कारणों से इसका उपयोग नहीं करना चाहते हैं।
  • मानव पठनीय फ़ाइलें आदि बनाने के लिए महंगी हैं। शायद इसके लायक नहीं है।
  • hdf5बड़ी फ़ाइलों के लिए कुछ कहा जाता है । ठंडा! https://stackoverflow.com/a/9619713/1601580

ध्यान दें कि यह एक संपूर्ण उत्तर नहीं है। लेकिन अन्य संसाधनों के लिए यह जाँच करें:

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.