اذهب إلى المحتوى

السؤال

نشر

لدي مصفوفة Numpy متعددة الأبعاد (5,3,2) وأريد أن أقوم بحفظ هذه المصفوفة في ملف نص، بحيث يمكنني إستخدامها لاحقًا. 

لذلك جربت الدالة numpy.savetxt. الغريب أنه يعطي الخطأ التالي:

TypeError: float argument required, not numpy.ndarray

أفترض أن هذا الدالة لا تعمل مع المصفوفات متعددة الأبعاد، كيف يمكني حفظ مصفوفة Numpy في ملف نص؟

Recommended Posts

  • 1
نشر

يمكنك حفظها من خلال الدالة save في نمباي، كملف من نوع NPY:

from numpy import asarray
from numpy import save
import numpy as np
# define data
data = np.arange(200).reshape((4,5,10))
# save
save('data.npy', data)
# load
from numpy import load
# load array
data = load('myarray.npy')
# طباعة جزء منها
print(data[0])
"""
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]]
"""

ويمكنك حفظها كملف مضغوط من خلال الدالة savez_compressed  كملف من نوع NPZ:

from numpy import savez_compressed
# define data
data = np.arange(200).reshape((4,5,10))
# save to npy file
savez_compressed('array.npz', data)

إن هذه الدالة تدعم عملية حفظ عدة مصفوفات ضمن ملف واحد، الآن إذا أردنا تحميلها فيمكننا القيام بذلك من خلال الدالة load أيضاً، لكن هنا سيتم تحميلها كقاموس لأنه كما قلنا هذه الدالة تدعم تخزين عدة مصفوفات وبالتالي قد تقوم load بتحميل عدة مصفوفات، ولهذا السبب تقوم هذه الدالة بتحميلها ك قاموس مفاتيحه arr_0 لأول مصفوفة، وفي حال تواجد مصفوفة أخرى arr_1 وهكذا.. هنا قمنا بحفظ مصفوفة واحدة أي سنجدها في arr_0 (ولايوجد غيرها:

# تحميلها من الملف
from numpy import load
# تحميلها كقاموس
data = load('array.npz')
# استخراج أول مصفوفة
subarray = data['arr_0']
# عرض جزء منها
print(subarray[0])
"""
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]
 [30 31 32 33 34 35 36 37 38 39]
 [40 41 42 43 44 45 46 47 48 49]]
"""

لكن في الطريقتين السابقتين، لا يمكننا فحص محتويات الملف المحفوظ باستخدام محرر نصوص لأن تنسيق الملف ثنائي.
الآن إذا أردت استخدام savetext من أجل أن تكون قادراً على قراءة محتوياته مثلاً من محرر النصوص، فسنلجأ لأحد الحلول وهو تقسيم المصفوفة ثلاثية الأبعاد (أو أكبر) إلى شرائح ثنائية الأبعاد. على سبيل المثال:

from numpy import savez_compressed
import scipy.io
# define data
data = np.arange(200).reshape((4,5,10))
with open('test.txt', 'w') as outfile:
    for slice_2d in data:
        np.savetxt(outfile, slice_2d)

لكن هدفك هو أن تكون قابلة للقراءة بشكل واضح، لذا يمكننا أن نكون أكثر دقة قليلاً وأن نلجأ لخدعة، عن طريق تفريق الشرائح باستخدام أسطر التعليقات #. بشكل افتراضي، سيتجاهل numpy.loadtxt أي سطور تبدأ بـ # (أو أي حرف يتم تحديده بواسطة kwarg التعليقات):

import numpy as np
# بياناتنا
data = np.arange(200).reshape((4,5,10))
# حفظ المصفوفة كملف
with open('data.txt', 'w') as f:
    # سنضيف ترويسة من أجل سهولة القراءة
    f.write('# Array shape: {0}\n'.format(data.shape)) # كما قلنا سيتم تجاهل أي سطر يبدأ ب
    
    # نقوم بإنتاج الشرائح عن طريق المرور على المصفوفة
    for slic1e in data:
        np.savetxt(f, slic1e, fmt='%-7.2f')
        # طبعاة الشريحة وطباعة عبارة تشير للانتقال لشريحة أخرى 
        f.write('# New slice\n')

الآن لإعادة تحميلها:

# طبعاً المصفوفة التي ستقرأ هي ثنائية
arr = np.loadtxt('test.txt')
# لذا نعود للثلاثية البعد بسهولة
arr = arr.reshape((4,5,10))
arr
"""
array([[[  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.],
        [ 10.,  11.,  12.,  13.,  14.,  15.,  16.,  17.,  18.,  19.],
        [ 20.,  21.,  22.,  23.,  24.,  25.,  26.,  27.,  28.,  29.],
        [ 30.,  31.,  32.,  33.,  34.,  35.,  36.,  37.,  38.,  39.],
        [ 40.,  41.,  42.,  43.,  44.,  45.,  46.,  47.,  48.,  49.]],
        ...
        ...
        ...
"""

 

  • 0
نشر

يمكن استعمال الطريقة التالية:

file.write("%g"*len(a)+"\n" % tuple(a))

حيث أن العملية "%g"*len(a) تسمح لنا بتجنب الخطأ.

أو كالتالي:

file.write(' '.join(str(a) for a in arr))

لتحويل المصفوفة لسلسلة نصية.

كما يمكن استخدام: numpy.ndarray.tofile:

ndarray.tofile(fid, sep='', format='%s')

حيث أن المعاملات بالترتيب, الملف ثم العلامة الفاصلة المطلوبة ثم التنسيق وهو سلسلة نصية

  • 0
نشر

يمكنك أيضاً استخدم 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()

وقم بقراءة الإجابات على هذا السؤال ستفيدك كثيراً في تنفيذ المطلوب

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...