सुन्न सरणियों के पायथन मेमोरी का उपयोग


156

मैं कुछ बड़ी फ़ाइलों का विश्लेषण करने के लिए अजगर का उपयोग कर रहा हूं और मैं स्मृति मुद्दों में चल रहा हूं, इसलिए मैं उपयोग करने के लिए प्रयास करने और रखने के लिए sys.getizeof () का उपयोग कर रहा हूं, लेकिन यह खस्ता सरणियों के साथ व्यवहार विचित्र है। यहाँ एक उदाहरण है जिसमें अल्बेडोस का एक नक्शा शामिल है जिसे मैं खोलने जा रहा हूँ:

>>> import numpy as np
>>> import struct
>>> from sys import getsizeof
>>> f = open('Albedo_map.assoc', 'rb')
>>> getsizeof(f)
144
>>> albedo = struct.unpack('%df' % (7200*3600), f.read(7200*3600*4))
>>> getsizeof(albedo)
207360056
>>> albedo = np.array(albedo).reshape(3600,7200)
>>> getsizeof(albedo)
80

वैसे अभी भी डेटा है, लेकिन ऑब्जेक्ट का आकार, 3600x7200 पिक्सेल का नक्शा, ~ 200 एमबी से 80 बाइट तक चला गया है। मैं आशा करना चाहता हूं कि मेरी मेमोरी के मुद्दे खत्म हो गए हैं और बस सब कुछ सुन्न सरणियों में बदल दिया है, लेकिन मुझे लगता है कि यह व्यवहार, अगर सच है, तो किसी तरह से सूचना सिद्धांत या थर्मोडायनामिक्स के कानून, या कुछ और का उल्लंघन होगा। विश्वास है कि getizeof () सुन्न सरणियों के साथ काम नहीं करता है के लिए इच्छुक है। कोई विचार?


8
डॉक्स पर से sys.getsizeof: "बाइट्स में किसी ऑब्जेक्ट का आकार लौटाएं। ऑब्जेक्ट किसी भी प्रकार की ऑब्जेक्ट हो सकता है। सभी अंतर्निहित ऑब्जेक्ट सही परिणाम लौटाएंगे, लेकिन यह तीसरे पक्ष के एक्सटेंशन के लिए सही नहीं है। कार्यान्वयन विशिष्ट। केवल ऑब्जेक्ट के लिए सीधे मेमोरी की खपत के लिए जिम्मेदार है, न कि उन वस्तुओं की मेमोरी खपत जो इसे संदर्भित करता है। "
जोएल कॉर्नेट

1
यह विशेष रूप से तृतीय पक्ष एक्सटेंशन के लिए getsizeofमेमोरी खपत का एक अविश्वसनीय संकेतक बनाता है ।
जोएल कॉर्नेट

13
असल में, यहाँ मुद्दा यह है कि resizeएक लौट रहा है view, एक नया सरणी नहीं। आपको दृश्य का आकार मिल रहा है, वास्तविक डेटा नहीं।
mgilson

उस अंत तक, sys.getsizeof(albedo.base)गैर-दृश्य का आकार देगा।
एरिक

जवाबों:


236

आप array.nbytesउदाहरण के लिए, खस्ता सरणियों के लिए उपयोग कर सकते हैं :

>>> import numpy as np
>>> from sys import getsizeof
>>> a = [0] * 1024
>>> b = np.array(a)
>>> getsizeof(a)
8264
>>> b.nbytes
8192

इसका sys.getsizeof (a), आयात sys करने के बाद।
Eddys

2
b.__sizeof__()के बराबर हैsys.getsizeof(b)
पलाश

1
round(getsizeof(a) / 1024 / 1024,2)MB पाने के लिए
gies0r

13

फ़ील्ड nbytes आपको सरणी के सभी तत्वों के बाइट्स में आकार देगा numpy.array:

size_in_bytes = my_numpy_array.nbytes

ध्यान दें कि यह "सरणी ऑब्जेक्ट के गैर-तत्व विशेषताओं" को मापता नहीं है, इसलिए बाइट्स में वास्तविक आकार इससे कुछ बाइट्स हो सकता है।


यह उत्तर अभी भी एक सरणी बनाता है, इसलिए मुझे लगता है कि आप "एक सूची से एक सरणी में बदलने की आवश्यकता के बिना" का मतलब है। हालांकि यह सच है कि GWW का जवाब पहले एक सूची बनाता है और फिर इसे एक सरणी में परिवर्तित करता है, जो कि बिंदु के बगल में है, क्योंकि ओपी में पहले से ही एक सरणी है ... बिंदु यह है कि कैसे एक संख्यात्मक सरणी का आकार प्राप्त किया जाए, इसलिए यह नहीं है महत्वपूर्ण यह है कि आपको पहली जगह में सरणी कैसे मिली। कोई भी इस उत्तर की आलोचना यह कह कर कर सकता है कि यह एक मौजूदा सारणी को पुनः आकार देता है।
मट

नमस्कार @ मूट, टिप्पणी के लिए धन्यवाद। सवाल यह है कि किसी सरणी के बाइट्स में आकार कैसे प्राप्त करें। जबकि यह सच है कि मेरा स्निपेट पहली बार एक सरणी बनाता है, यह केवल एक पूर्ण उदाहरण होने के उद्देश्य से है जिसे निष्पादित किया जा सकता है। मैं इस तनाव को दूर करने के लिए अपने उत्तर को संपादित करूंगा।
एल मार्स

1

अजगर पुस्तिकाओं में मैं अक्सर बाहर फिल्टर करने के लिए 'झूलने' चाहते numpy.ndarrayहै, विशेष रूप से जो कि में जमा हो जाती _1, _2, आदि है कि वास्तव में मतलब कभी नहीं थे जीवित रहने के लिए।

मैं उन सभी और उनके आकार की सूची प्राप्त करने के लिए इस कोड का उपयोग करता हूं।

यकीन नहीं हो रहा है locals()या globals()यहाँ बेहतर है।

import sys
import numpy
from humanize import naturalsize

for size, name in sorted(
    (value.nbytes, name)
    for name, value in locals().items()
    if isinstance(value, numpy.ndarray)):
  print("{:>30}: {:>8}".format(name, naturalsize(size)))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.