Sayısal dizilerin Python bellek kullanımı


156

Bazı büyük dosyaları analiz etmek için python kullanıyorum ve bellek sorunları ile çalışıyorum, bu yüzden kullanımı takip etmek ve denemek için sys.getsizeof () kullanıyorum, ancak numpy dizileri ile davranış tuhaf. İşte açmak zorunda olduğum bir albedos haritasını içeren bir örnek:

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

Veriler hala orada, ancak nesnenin boyutu, 3600x7200 piksel bir harita, ~ 200 Mb'dan 80 bayta çıktı. Bellek sorunlarımın bittiğini ve sadece her şeyi numpy dizilerine dönüştürdüğünü ummak isterim, ancak doğruysa bu davranışın bir şekilde bilgi teorisi veya termodinamik yasalarını veya bir şeyi ihlal edeceğini hissediyorum. getsizeof () yönteminin sayısal dizilerle çalışmadığına inanmaya meyilli. Herhangi bir fikir?


8
Dokümanlarda sys.getsizeof: "Bir nesnenin boyutunu bayt cinsinden döndür. Nesne herhangi bir nesne türü olabilir. Tüm yerleşik nesneler doğru sonuçları döndürür, ancak bunun üçüncü taraf uzantıları için geçerli olması gerekmez. Uygulamaya özel. Yalnızca söz konusu nesnelerle ilişkilendirilen bellek tüketimi, söz konusu nesnelerin bellek tüketimini hesaba katmaz. "
Joel Cornett

1
Bu getsizeof, özellikle 3. taraf uzantıları için bellek tüketiminin güvenilir olmayan bir göstergesidir .
Joel Cornett

13
Temel olarak, burada sorun yeni bir dizi değil resize, bir döndürüyor olmasıdır view. Gerçek veriyi değil, görünümün boyutunu elde edersiniz.
mgilson

Bu amaçla, sys.getsizeof(albedo.base)görüntülememenin boyutunu verecektir.
Eric

Yanıtlar:


236

array.nbytesNumpy dizileri için kullanabilirsiniz , örneğin:

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

Onun ithalat sistemi yaptıktan sonra sys.getsizeof (a).
eddys

2
b.__sizeof__()eşittirsys.getsizeof(b)
palash

1
round(getsizeof(a) / 1024 / 1024,2)MB almak için
gies0r

13

Nbytes alanı size dizideki tüm öğelerin bayt cinsinden boyutunu verir numpy.array:

size_in_bytes = my_numpy_array.nbytes

Bunun "dizi nesnesinin öğe olmayan özniteliklerini" ölçmediğine dikkat edin, böylece bayttaki gerçek boyut bundan birkaç bayt daha büyük olabilir.


Bu cevap hala bir dizi oluşturur, bu yüzden "bir listeden bir diziye dönüştürmeye gerek kalmadan" demek istediğinizi düşünüyorum. Her ne kadar GWW'nin cevabının önce bir liste oluşturup ardından bir diziye dönüştürdüğü doğru olsa da, OP zaten bir diziye sahip olduğundan, noktanın yanı sıra ... Nokta, numpy dizinin boyutunu nasıl alacağınızdır, bu yüzden diziyi ilk etapta nasıl aldığınız konusunda kritik. Benzer şekilde, mevcut bir diziyi yeniden şekillendirdiğini söyleyerek de bu cevabı eleştirebilir.
Moot

Merhaba @Moot, yorum için teşekkürler. Soru, bir dizinin bayt cinsinden boyutun nasıl alınacağıyla ilgilidir. Parçamın ilk önce bir dizi oluşturduğu doğru olsa da, yalnızca çalıştırılabilecek tam bir örneğe sahip olmak içindir. Bunu vurgulamak için cevabımı düzenleyeceğim.
El Marce

1

Piton dizüstü ben sık sık 'sarkan' filtrelemek istiyorum numpy.ndarray'ler, özellikle depolanan olanlar _1, _2gerçekten biz olduk, vb hayatta kalmak için.

Hepsini ve boyutlarını bir liste almak için bu kodu kullanın.

Olmadığından emin değil misiniz locals()veya globals()daha burada.

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