2011-08-05 31 views
13

Anladığım kadarıyla, Python'daki list türü, öğeler eklendiğinde kapasitesini artıracak dinamik bir işaretçi dizisidir. NumPy'deki bir dizi, dizinin tüm verilerini tutmak için sürekli bir bellek alanı kullanır.Dinamik bir dizi oluşturma

Kapasitesini bir liste olarak dinamik olarak artıran ve değeri bir NumPy dizisi olarak saklayan türde var mı? C# gibi bir şey gibi bir şey. Ve tür bir NumPy dizisi ile aynı arabirime sahipse harika.

İçerideki NumPy dizi sarar bir sınıf oluşturmak ve bu gibi dolu olduğunda bu diziyi boyutlandırabilirsiniz

:

class DynamicArray(object): 
    def __init__(self): 
     self._data = np.zeros(100) 
     self._size = 0 

    def get_data(self): 
     return self._data[:self._size] 

    def append(self, value): 
     if len(self._data) == self._size: 
      self._data = np.resize(self._data, int(len(self._data)*1.25)) 
     self._data[self._size] = value 
     self._size += 1 

ama DynamicArray bir NumPy dizi olarak kullanılamaz ve bütün düşünüyorum np.resize() önce get_data() tarafından döndürülen görünümler eski diziyi tutacaktır.

Düzenleme: dizi modülündeki dizi türü dinamik dizi. Grafikten

from array import array 
import time 
import numpy as np 
import pylab as pl 

def test_time(func): 
    arrs = [func() for i in xrange(2000)] 
    t = [] 
    for i in xrange(2000): 
     start = time.clock() 
     for a in arrs: 
      a.append(i) 
     t.append(time.clock()-start) 
    return np.array(t) 

t_list = test_time(lambda:[]) 
t_array = test_time(lambda:array("d")) 
pl.subplot(211) 
pl.plot(t_list, label="list") 
pl.plot(t_array, label="array") 
pl.legend() 
pl.subplot(212) 
pl.plot(np.where(t_list>2*np.median(t_list))[0]) 
pl.plot(np.where(t_array>2*np.median(t_array))[0]) 
pl.show() 

enter image description here

: aşağıdaki program listesi ve dizinin bir artış katsayısı test etmek listenin artış faktörü dizisi daha büyüktür.

+1

Bu numpy'nin bir ekleme işlevinin olduğunu biliyorsunuz, değil mi? Verilerin bir kopyasını oluşturur, ancak daha sonra yukarıda kullandığınız "numpy.resize" yapar. Eğer istediğini yapmazsan, neden bunu istediğini biraz daha açıklayabilir misin? – senderle

+0

@senderle: Evet Ekleme işlevini biliyorum, ancak doluluk oranını 1,25 gibi bir faktörle dolduran dinamik bir diziye ihtiyacım var. – HYRY

cevap

13

Sen Python standart kütüphane de sadece ne istediğinizi gibi sesler bir array modül içerdiğini bilmek ilginizi çekebilir:

Bu modül kompakt temel değerler dizi temsil edebilir bir nesne türünü tanımlar : karakterler, tamsayılar, kayan nokta sayıları. Diziler, dizi türleridir ve listelere çok benzer davranırlar; bunun dışında, , içinde saklanan nesnelerin türü kısıtlanır.

+0

Teşekkürler. Bu dizinin append() yöntemini bilmedim. NumPy'de benzer bir tür varsa, harika olacaktır çünkü bu dinamik dizi ile hesaplama yapmak için ufunc kullanmak istiyorum. – HYRY

+0

@ user772649, değerinin ne olduğu için, '' 'dizinin' append 'yöntemi kapasitesini bir faktörle artırmaz - kapasitesini tam olarak artırır. Aynı şekilde, 'extend' yöntemi, kapasitesini tam olarak eklenen öğe sayısı kadar artırır. – senderle

+0

@senderle, Dizinin yeniden boyutlandırma yöntemini, daha fazla zaman kullanacağı için yeniden boyutlandırdığı zaman, maliyetini ölçerek test ettim. Orijinal soruyu düzenledim ve artış grafiğini ekledim. Grafikten, dizi sayısının listeden küçük olan faktör artışını görebilirsiniz. – HYRY