527 votes

Pourquoi des listes NumPy au lieu de Python ?

Vaut-il mon apprentissage NumPy?

J'ai environ 100 marchés financiers de la série, et je vais créer un cube tableau de 100x100x100 = 1 million de cellules. Je vais être en régression (3-variable) chaque x avec chaque y et z, remplir le tableau avec les erreurs standard.

J'ai entendu dire que pour les "grandes matrices" je devrais utiliser NumPy contrairement à Python, les listes, les performances et l'évolutivité des raisons. La chose est, je sais Python listes et ils semblent fonctionner pour moi.

Est l'ampleur du problème ci-dessus vaut le déplacement pour NumPy?

Que faire si j'ai eu de la série 1000 (soit 1 milliard de dollars à virgule flottante cellules du cube)?

791voto

Alex Martelli Points 330805

NumPy est tableaux sont plus compacts que les listes Python-une liste de listes que vous le décrivez, en Python, faudrait au moins 20 MO, tandis qu'un NumPy tableau 3D avec de simple précision flotte dans les cellules correspondrait à 4 MO. L'accès à la lecture et à l'écriture des articles est également plus rapide avec NumPy.

Peut-être que vous ne vous souciez pas tant que ça pour seulement un million de cellules, mais vous avez certainement pour un milliard de cellules -- aucune approche permettrait de s'intégrer dans une architecture 32 bits, mais avec des versions 64 bits NumPy pouvait s'échapper avec 4 GO ou alors, Python seul aurait besoin d'au moins environ 12 GO (beaucoup de pointeurs qui double de volume) -- un beaucoup plus coûteux morceau de matériel!

La différence est principalement due à la "indirectness" -- une liste Python est un tableau de pointeurs vers des objets Python, au moins 4 octets par pointeur de plus de 16 octets, même pour le plus petit objet Python (4 pour le type pointeur, 4 pour le compte de référence, 4 pour la valeur -- et la mémoire allocateurs de tours jusqu'à 16). Un tableau NumPy est un tableau de valeurs uniformes -- nombres simple précision prend 4 octets chacun, double précision, de 8 octets. Moins souple, mais vous payez considérablement la souplesse des standards de Python, les listes!

255voto

Roberto Bonvallet Points 6336

Numpy est pas seulement plus efficace, il est aussi plus pratique. Vous obtenez beaucoup de vecteur et matrice des opérations pour libre, qui permettent parfois d'éviter le travail inutile. Et ils sont aussi efficacement mis en œuvre.

Par exemple, vous pouvez lire votre cube directement à partir d'un fichier dans un tableau:

x = numpy.fromfile(file=open("data"), dtype=float).reshape((100, 100, 100))

Somme le long de la deuxième dimension:

s = x.sum(axis=1)

Trouver laquelle les cellules sont au-dessus d'un seuil:

(x > 0.5).nonzero()

Supprimer tous les même indexé tranche le long de la troisième dimension:

x[:, :, ::2]

Aussi, d'autres bibliothèques qui pourrait être utile pour vous de travailler sur des tableaux numpy. Par exemple, l'analyse statistique et de visualisation des bibliothèques.

Même si vous n'avez pas de problèmes de performance, l'apprentissage numpy est la valeur de l'effort.

119voto

tom10 Points 19886

Alex mentionné l'efficacité de mémoire, et Roberto mentionne commodité, et ce sont deux bons points. Pour un peu plus d'idées je vais vous parler de la vitesse et de fonctionnalité.

Fonctionnalité: Vous obtenez beaucoup construit en avec Numpy, Fft, circonvolutions, la recherche rapide, les statistiques de base, l'algèbre linéaire, histogrammes, etc. Et vraiment, qui ne peuvent vivre sans Fft?

Vitesse: Voici un test à faire une somme sur une liste et un tableau numpy, montrant que la somme sur le tableau numpy est 10x plus rapide (dans ce test -- kilométrage peut varier).

from numpy import arange
from timeit import Timer

Nelements = 10000
Ntimeits = 10000

x = arange(Nelements)
y = range(Nelements)

t_numpy = Timer("x.sum()", "from __main__ import x")
t_list = Timer("sum(y)", "from __main__ import y")
print "numpy: %.3e" % (t_numpy.timeit(Ntimeits)/Ntimeits,)
print "list:  %.3e" % (t_list.timeit(Ntimeits)/Ntimeits,)

qui sur mes systèmes (alors que je suis en cours d'exécution d'une sauvegarde) donne:

numpy: 3.004e-05
list:  5.363e-04

16voto

David Cournapeau Points 21956

Notez également qu’il n’y a timeseries basé sur numpy dans le scikits timeseries en faveur :

http://pytseries.sourceforge.net

Pour la régression, je suis sûr que numpy sera l’ordre de grandeur plus rapide et plus pratique que les listes de même pour les 100 ^ 3 problème

-5voto

Arijan Points 1

Vitesse sage je ne suis pas si sûr. Voici un exemple rapide: j'ai créé une fonction(de x) qui retourne une liste de nombres premiers entre 2 et x:

  • régulier de la fonction python à l'aide de listes:

    def findprimeupto(x):
        primes = []
        n_primes = []
    
        for i in range(2, x):
    
            if not (i in n_primes):
                primes.append(i)
                n_primes.append(i)
    
            for j in range(len(primes)):
                if i > n_primes[j]:
                    n_primes[j] += primes[j]
    
        return primes
    
    import time
    start_time = time.time()
    findprimeupto(10000)
    print("--- %s seconds ---" % str(time.time() - start_time))
    
  • et C comme fonction python à l'aide de tableaux numpy:

    import numpy
    
    
    def findprimeupto(x):
    
        primes = numpy.array(numpy.zeros(x), dtype=numpy.int32)
        n_primes = numpy.array(numpy.zeros(x), dtype=numpy.int32)
        primeslen = 0
    
        for i in range(2, x):
    
            flag = 1
            for j in range(primeslen):
                if n_primes[j] == i:
                    flag = 0
                    break
    
            if flag:
                primes[primeslen] = i
                n_primes[primeslen] = i
                primeslen += 1
    
            for j in range(primeslen):
                if i > n_primes[j]:
                    n_primes[j] += primes[j]
    
        return [primeslen, primes]
    
    
    import time
    
    start_time = time.time()
    
    result = findprimeupto(10000)
    
    #for i in range(result[0]):
    #    print('{:d} '.format(result[1][i]), end="")
    
    print()
    print("--- %s seconds ---" % str(time.time() - start_time))
    

L'ancien, soi-disant lenteur de mise en œuvre à l'aide de listes, est exécuté en 0,6 seconde et la plus tard, soi-disant rapide numpy mise en œuvre, les besoins en 50 secondes. Si quelqu'un peut rappeler pourquoi je serais très heureux.

BTW pur programme C qui est plus ou moins une copie de numpy version de la fonction s'exécute en moins de 0,04 s. La vitesse de C est encore plus évident avec grand x:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    void findprimesupto(int n, int *primeslen, int *primes, int *n_primes) {
        int i, j, flag;

        *primeslen = 0;

        for (i=2; i <= n; i++) {
            for (j=0, flag=1; j < *primeslen; j++)
                if (n_primes[j] == i) {
                    flag = 0;
                    break;
                }
            if (flag) {
                primes[*primeslen] = i;
                n_primes[*primeslen] = i;
                (*primeslen)++;
            }
            for (j=0; j < *primeslen; j++)
                if (i > n_primes[j])
                    n_primes[j] += primes[j];
        }
    }

    int main() {
        int n = 10000, primeslen = 0, i;
        int *primes, *n_primes;
        clock_t start, diff;

        start = clock();
        primes = malloc(n * sizeof(int));
        n_primes = malloc(n * sizeof(int));

        findprimesupto(n, &primeslen, primes, n_primes);

        /* for (i=0; i < primeslen; i++)
            printf("%d ", primes[i]);

        printf("\n");
        */

        diff = clock() - start;
        printf("Time: %f s\n", (float) diff / (float) CLOCKS_PER_SEC);

        free(primes);
        free(n_primes);

        return 0;
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X