2011-08-05 4 views
13

Si je comprends bien, le type list en Python est un tableau de pointeur dynamique, ce qui augmentera sa capacité lorsque des éléments sont ajoutés à elle. Et un tableau dans NumPy utilise une zone de mémoire continue pour contenir toutes les données du tableau.Comment créer un tableau dynamique

Existe-t-il des types qui augmentent de manière dynamique sa capacité en tant que liste, et stocke la valeur en tant que tableau NumPy? Quelque chose comme List in C#. Et c'est génial si le type a la même interface qu'un tableau NumPy.

Je peux créer une classe qui encapsule un tableau numpy à l'intérieur, et redimensionner ce tableau quand il est plein, comme:

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 

mais DynamicArray ne peut pas être utilisé comme tableau numpy, et je pense que tous les les vues renvoyées par get_data() avant que np.resize() ne contienne l'ancien tableau.

Edit: type de réseau dans le module de tableau est un tableau dynamique. Le programme suivant tester le facteur d'augmentation de la liste et tableau:

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

du graphique: le facteur d'augmentation de la liste est plus grand que tableau.

+1

Vous ne savez que numpy a une fonction append, non? Il crée une copie des données, mais il en est de même pour 'numpy.resize' que vous utilisez ci-dessus. Si cela ne fait pas ce que vous voulez, pourriez-vous expliquer un peu plus pourquoi vous le voulez? – senderle

+0

@senderle: Oui, je connais la fonction d'ajout, mais j'ai besoin d'un tableau dynamique qui augmente sa capacité d'un facteur tel que 1,25 quand il est plein. – HYRY

Répondre

13

Vous pouvez être intéressé de savoir que la bibliothèque standard Python comprend également un module array qui ressemble à tout ce que vous voulez:

Ce module définit un type d'objet qui peut compacte représenter un tableau des valeurs de base : caractères, entiers, nombres à virgule flottante. Les tableaux sont types de séquence et se comportent comme des listes, sauf que le type d'objets stockés dans les est contraint.

+0

merci. Je ne savais pas que ce tableau a la méthode append(). Ce sera génial s'il y a un type similaire dans NumPy, parce que je veux utiliser ufuncs pour faire des calculs avec ce tableau dynamique. – HYRY

+0

@ user772649, pour ce que ça vaut, la méthode 'append' d'un' array' n'augmente pas sa capacité d'un facteur - elle augmente sa capacité d'exactement un. De même, la méthode 'extend' augmente sa capacité d'exactement le nombre d'éléments ajoutés. – senderle

+0

@senderle, j'ai testé la méthode append de array en mesurant le temps qu'il a coûté, puisque redimensionner le tableau va utiliser plus de temps. J'ai édité la question originale et ajouté le graphique d'augmentation. À partir du graphique, vous pouvez voir ce tableau augmenter par facteur, qui est petit que liste. – HYRY

Questions connexes