टेक्स्ट फ़ाइल में बहुआयामी सरणी कैसे लिखें?


115

एक अन्य प्रश्न में, अन्य उपयोगकर्ताओं ने कुछ मदद की पेशकश की अगर मैं उस सरणी की आपूर्ति कर सकता हूं जिसके साथ मैं परेशान था। हालाँकि, मैं एक मूल I / O कार्य में भी विफल रहता हूं, जैसे कि किसी फ़ाइल में सरणी लिखना।

क्या कोई समझा सकता है कि मुझे किस तरह के लूप को फाइल करने के लिए एक 4x11x14 के अंक के लिए लिखना होगा?

इस सरणी में चार 11 x 14 सरणियाँ शामिल हैं, इसलिए मुझे इसे एक अच्छी नई पंक्ति के साथ प्रारूपित करना चाहिए, ताकि दूसरों पर फ़ाइल को पढ़ना आसान हो सके।

संपादित करें : तो मैंने numpy.savetxt फ़ंक्शन की कोशिश की है। अजीब बात है, यह निम्नलिखित त्रुटि देता है:

TypeError: float argument required, not numpy.ndarray

मुझे लगता है कि यह इसलिए है क्योंकि फ़ंक्शन बहुआयामी सरणियों के साथ काम नहीं करता है? किसी भी समाधान के रूप में मैं उन्हें एक फ़ाइल के भीतर करना चाहते हैं?

जवाबों:


197

यदि आप इसे डिस्क पर लिखना चाहते हैं, तो इसे वापस एक सुव्यवस्थित सरणी के रूप में पढ़ना आसान होगा, पर गौर करें numpy.save। अचार बनाना ठीक काम करेगा, लेकिन यह बड़े सरणियों के लिए कम कुशल है (जो कि आपका नहीं है, इसलिए या तो पूरी तरह से ठीक है)।

यदि आप चाहते हैं कि यह मानव पठनीय हो, तो देखें numpy.savetxt

संपादित करें: तो, ऐसा लगता है जैसे savetxt> 2 आयामों के साथ सरणियों के लिए बहुत अच्छा विकल्प नहीं है ... लेकिन यह सब कुछ बाहर निकालने के लिए पूर्ण निष्कर्ष है:

मुझे बस एहसास हुआ कि numpy.savetxt2 से अधिक आयामों के साथ ndarrays पर चुटकुले ... यह संभवतः डिज़ाइन द्वारा है, क्योंकि टेक्स्ट फ़ाइल में अतिरिक्त आयामों को इंगित करने के लिए कोई अंतर्निहित तरीका नहीं है।

जैसे यह (एक 2D सरणी) ठीक काम करता है

import numpy as np
x = np.arange(20).reshape((4,5))
np.savetxt('test.txt', x)

जबकि TypeError: float argument required, not numpy.ndarray3 डी सरणी के लिए एक ही चीज़ विफल होगी (बल्कि एक असंक्रामक त्रुटि के साथ ):

import numpy as np
x = np.arange(200).reshape((4,5,10))
np.savetxt('test.txt', x)

एक वर्कअराउंड 3 डी (या अधिक) सरणी को 2 डी स्लाइस में तोड़ना है। उदाहरण के लिए

x = np.arange(200).reshape((4,5,10))
with file('test.txt', 'w') as outfile:
    for slice_2d in x:
        np.savetxt(outfile, slice_2d)

हालांकि, हमारा लक्ष्य स्पष्ट रूप से मानव पठनीय होना है, जबकि अभी भी आसानी से वापस पढ़ा जा रहा है numpy.loadtxt। इसलिए, हम थोड़ा और अधिक वर्बोज़ हो सकते हैं, और टिप्पणी लाइनों का उपयोग करके स्लाइस को अलग कर सकते हैं। डिफ़ॉल्ट रूप से, (जो भी वर्ण kwarg द्वारा निर्दिष्ट है ) के numpy.loadtxtसाथ शुरू होने वाली किसी भी रेखा को अनदेखा करेगा । (यह वास्तव में है की तुलना में अधिक क्रिया लगता है ...)#comments

import numpy as np

# Generate some test data
data = np.arange(200).reshape((4,5,10))

# Write the array to disk
with open('test.txt', 'w') as outfile:
    # I'm writing a header here just for the sake of readability
    # Any line starting with "#" will be ignored by numpy.loadtxt
    outfile.write('# Array shape: {0}\n'.format(data.shape))

    # Iterating through a ndimensional array produces slices along
    # the last axis. This is equivalent to data[i,:,:] in this case
    for data_slice in data:

        # The formatting string indicates that I'm writing out
        # the values in left-justified columns 7 characters in width
        # with 2 decimal places.  
        np.savetxt(outfile, data_slice, fmt='%-7.2f')

        # Writing out a break to indicate different slices...
        outfile.write('# New slice\n')

यह प्रदान करता है:

# Array shape: (4, 5, 10)
0.00    1.00    2.00    3.00    4.00    5.00    6.00    7.00    8.00    9.00   
10.00   11.00   12.00   13.00   14.00   15.00   16.00   17.00   18.00   19.00  
20.00   21.00   22.00   23.00   24.00   25.00   26.00   27.00   28.00   29.00  
30.00   31.00   32.00   33.00   34.00   35.00   36.00   37.00   38.00   39.00  
40.00   41.00   42.00   43.00   44.00   45.00   46.00   47.00   48.00   49.00  
# New slice
50.00   51.00   52.00   53.00   54.00   55.00   56.00   57.00   58.00   59.00  
60.00   61.00   62.00   63.00   64.00   65.00   66.00   67.00   68.00   69.00  
70.00   71.00   72.00   73.00   74.00   75.00   76.00   77.00   78.00   79.00  
80.00   81.00   82.00   83.00   84.00   85.00   86.00   87.00   88.00   89.00  
90.00   91.00   92.00   93.00   94.00   95.00   96.00   97.00   98.00   99.00  
# New slice
100.00  101.00  102.00  103.00  104.00  105.00  106.00  107.00  108.00  109.00 
110.00  111.00  112.00  113.00  114.00  115.00  116.00  117.00  118.00  119.00 
120.00  121.00  122.00  123.00  124.00  125.00  126.00  127.00  128.00  129.00 
130.00  131.00  132.00  133.00  134.00  135.00  136.00  137.00  138.00  139.00 
140.00  141.00  142.00  143.00  144.00  145.00  146.00  147.00  148.00  149.00 
# New slice
150.00  151.00  152.00  153.00  154.00  155.00  156.00  157.00  158.00  159.00 
160.00  161.00  162.00  163.00  164.00  165.00  166.00  167.00  168.00  169.00 
170.00  171.00  172.00  173.00  174.00  175.00  176.00  177.00  178.00  179.00 
180.00  181.00  182.00  183.00  184.00  185.00  186.00  187.00  188.00  189.00 
190.00  191.00  192.00  193.00  194.00  195.00  196.00  197.00  198.00  199.00 
# New slice

जब तक हम मूल सरणी के आकार को जानते हैं, तब तक इसे पढ़ना बहुत आसान है। हम बस कर सकते हैं numpy.loadtxt('test.txt').reshape((4,5,10))। एक उदाहरण के रूप में (आप इसे एक पंक्ति में कर सकते हैं, मैं सिर्फ चीजों को स्पष्ट करने के लिए क्रिया कर रहा हूं):

# Read the array from disk
new_data = np.loadtxt('test.txt')

# Note that this returned a 2D array!
print new_data.shape

# However, going back to 3D is easy if we know the 
# original shape of the array
new_data = new_data.reshape((4,5,10))

# Just to check that they're the same...
assert np.all(new_data == data)

2
मेरे से +1, यह भी देखें numpy.loadtxt( docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html )
डोमिनिक रॉजर

2
यहाँ इस समस्या के लिए अब एक बहुत ही आसान समाधान है: yourStrArray = np.array ([yourMulDArray में वैल के लिए str (val)], dtype = 'string'); np.savetxt ('YourTextFile.txt', yourStrArray, fmt = '% s')
ग्रेग क्रामिडा

@GregKramida और आप सरणी कैसे पुनर्प्राप्त करते हैं?
एस्ट्रोजूनलू

@ Juanlu001: मुझे पता है कि numpy.loadtxt (...) एक dtype तर्क को भी स्वीकार करता है, जिसे np.string_ पर सेट किया जा सकता है। मुझे लगता है कि एक शॉट, पहले और फॉर्मूले देंगे। तार से सरणियों को पार्स करने के लिए एक numpy.fromstring (...) भी है।
ग्रेग क्रामिदा

अरे क्या होगा अगर मुझे एक छवि सरणी संग्रहीत करने की आवश्यकता है? हम यह कैसे आकार देंगे कि यदि छवि का आकार, 512 x 512 है?
अंबिका सक्सेना

31

मुझे यकीन नहीं है कि अगर यह आपकी आवश्यकताओं को पूरा करता है, तो मुझे लगता है कि आप लोगों द्वारा फ़ाइल को पठनीय बनाने में रुचि रखते हैं, लेकिन अगर यह प्राथमिक चिंता नहीं है, तो बस pickle

इसे बचाने के लिए:

import pickle

my_data = {'a': [1, 2.0, 3, 4+6j],
           'b': ('string', u'Unicode string'),
           'c': None}
output = open('data.pkl', 'wb')
pickle.dump(my_data, output)
output.close()

इसे वापस पढ़ने के लिए:

import pprint, pickle

pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

pkl_file.close()

pprintशब्दकोश मुद्रित करने के लिए आपको आवश्यकता नहीं हो सकती है ।
zyy

11

यदि आपको मानव-पठनीय आउटपुट की आवश्यकता नहीं है, तो एक और विकल्प जो आप कोशिश कर सकते हैं वह है सरणी को MATLAB .matफ़ाइल के रूप में सहेजना , जो एक संरचित सरणी है। मैं MATLAB से घृणा करता हूं, लेकिन यह तथ्य कि मैं दोनों .matको बहुत कम पंक्तियों में पढ़ और लिख सकता हूं , सुविधाजनक है।

जो किंगटन के जवाब के विपरीत, इसका लाभ यह है कि आपको फ़ाइल में डेटा के मूल आकार को जानने की आवश्यकता नहीं है.mat , अर्थात पढ़ने में कोई फेरबदल करने की आवश्यकता नहीं है। और, इसके विपरीत pickle, .matफ़ाइल को MATLAB द्वारा पढ़ा जा सकता है। और शायद कुछ अन्य कार्यक्रम / भाषाएं भी।

यहाँ एक उदाहरण है:

import numpy as np
import scipy.io

# Some test data
x = np.arange(200).reshape((4,5,10))

# Specify the filename of the .mat file
matfile = 'test_mat.mat'

# Write the array to the mat file. For this to work, the array must be the value
# corresponding to a key name of your choice in a dictionary
scipy.io.savemat(matfile, mdict={'out': x}, oned_as='row')

# For the above line, I specified the kwarg oned_as since python (2.7 with 
# numpy 1.6.1) throws a FutureWarning.  Here, this isn't really necessary 
# since oned_as is a kwarg for dealing with 1-D arrays.

# Now load in the data from the .mat that was just saved
matdata = scipy.io.loadmat(matfile)

# And just to check if the data is the same:
assert np.all(x == matdata['out'])

यदि आप उस कुंजी को भूल जाते हैं जो .matफ़ाइल में सरणी का नाम है , तो आप हमेशा ऐसा कर सकते हैं:

print matdata.keys()

और निश्चित रूप से आप कई और कुंजी का उपयोग करके कई सरणियों को स्टोर कर सकते हैं।

तो हां - यह आपकी आंखों के साथ पढ़ने योग्य नहीं होगा, लेकिन डेटा लिखने और पढ़ने के लिए केवल 2 लाइनें लगती हैं, जो मुझे लगता है कि एक उचित व्यापार-बंद है।

Scipy.io.savemat और scipy.io.loadmat और इस ट्यूटोरियल पृष्ठ के लिए डॉक्स पर एक नज़र डालें : scipy.io फ़ाइल IO ट्यूटोरियल


9

ndarray.tofile() काम भी करना चाहिए

उदाहरण के लिए, यदि आपका सरणी कहा जाता है a:

a.tofile('yourfile.txt',sep=" ",format="%s")

हालांकि यह सुनिश्चित करने के लिए नहीं कि न्यूलाइन फॉर्मेटिंग कैसे हो।

संपादित करें (केविन जे। ब्लैक की टिप्पणी यहां ):

संस्करण 1.5.0 के बाद से, मल्टी-लाइन आउटपुट की अनुमति देने के लिए np.tofile()एक वैकल्पिक पैरामीटर लेता है newline='\n'https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.savetxt.html


लेकिन क्या टेक्सफाइल से मूल सरणी बनाने का एक तरीका है?
आशान आलम सोजिब


tofileनहीं है newline='\n'
निको श्लोमर


1

आप केवल तीन नेस्टेड लूप में सरणी को पार कर सकते हैं और अपनी फ़ाइल में उनके मान लिख सकते हैं। पढ़ने के लिए, आप बस उसी सटीक लूप निर्माण का उपयोग करते हैं। आपको अपने सरणियों को फिर से सही ढंग से भरने के लिए बिल्कुल सही क्रम में मान मिलेगा।


0

मेरे पास इसे बस फ़ाइलनाम.राइट () ऑपरेशन का उपयोग करने का एक तरीका है। यह मेरे लिए ठीक काम करता है, लेकिन मैं ~ 1500 डेटा तत्वों वाले सरणियों के साथ काम कर रहा हूं।

मेरे पास मूल रूप से फाइल के माध्यम से लूप के लिए है और इसे एक सीएसवी स्टाइल आउटपुट में आउटपुट डेस्टिनेशन लाइन-बाय-लाइन पर लिखना है।

import numpy as np

trial = np.genfromtxt("/extension/file.txt", dtype = str, delimiter = ",")

with open("/extension/file.txt", "w") as f:
    for x in xrange(len(trial[:,1])):
        for y in range(num_of_columns):
            if y < num_of_columns-2:
                f.write(trial[x][y] + ",")
            elif y == num_of_columns-1:
                f.write(trial[x][y])
        f.write("\n")

डेटा तत्वों के बीच अल्पविराम जोड़ने के लिए if और elif स्टेटमेंट का उपयोग किया जाता है। जो भी कारण के लिए, इन फाइल को एनडी एरे के रूप में पढ़ते समय निकाल दिया जाता है। मेरा लक्ष्य फ़ाइल को सीएसवी के रूप में आउटपुट करना था, इसलिए यह विधि इसे संभालने में मदद करती है।

उम्मीद है की यह मदद करेगा!


0

इन मामलों के लिए अचार सबसे अच्छा है। मान लीजिए कि आपके पास नामधारी है x_train। आप इसे एक फ़ाइल में डंप कर सकते हैं और निम्नलिखित कमांड का उपयोग करके इसे वापस ला सकते हैं:

import pickle

###Load into file
with open("myfile.pkl","wb") as f:
    pickle.dump(x_train,f)

###Extract from file
with open("myfile.pkl","rb") as f:
    x_temp = pickle.load(f)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.