web-dev-qa-db-fra.com

Que signifie [:,:] sur les tableaux NumPy

Désolé pour la question stupide. Je programme sur PHP mais j'ai trouvé du bon code sur Python et je veux le "recréer" sur PHP. Mais je suis assez frustré par la ligne

self.h = -0.1    
self.activity = numpy.zeros((512, 512)) + self.h
self.activity[:, :] = self.h

Mais je ne comprends pas

[:, :]

signifier.

De plus, je n'ai pas pu "Google It".

Code complet

import math
import numpy
import pygame
from scipy.misc import imsave
from scipy.ndimage.filters import gaussian_filter


class AmariModel(object):

    def __init__(self, size):
        self.h = -0.1
        self.k = 0.05
        self.K = 0.125
        self.m = 0.025
        self.M = 0.065

        self.stimulus = -self.h * numpy.random.random(size)
        self.activity = numpy.zeros(size) + self.h
        self.excitement = numpy.zeros(size)
        self.inhibition = numpy.zeros(size)

    def stimulate(self):
        self.activity[:, :] = self.activity > 0

        sigma = 1 / math.sqrt(2 * self.k)
        gaussian_filter(self.activity, sigma, 0, self.excitement, "wrap")
        self.excitement *= self.K * math.pi / self.k

        sigma = 1 / math.sqrt(2 * self.m)
        gaussian_filter(self.activity, sigma, 0, self.inhibition, "wrap")
        self.inhibition *= self.M * math.pi / self.m

        self.activity[:, :] = self.h
        self.activity[:, :] += self.excitement
        self.activity[:, :] -= self.inhibition
        self.activity[:, :] += self.stimulus


class AmariMazeGenerator(object):

    def __init__(self, size):
        self.model = AmariModel(size)

        pygame.init()
        self.display = pygame.display.set_mode(size, 0)
        pygame.display.set_caption("Amari Maze Generator")

    def run(self):
        pixels = pygame.surfarray.pixels3d(self.display)

        index = 0
        running = True
        while running:
            self.model.stimulate()

            pixels[:, :, :] = (255 * (self.model.activity > 0))[:, :, None]
            pygame.display.flip()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                Elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False
                    Elif event.key == pygame.K_s:
                        imsave("{0:04d}.png".format(index), pixels[:, :, 0])
                        index = index + 1
                Elif event.type == pygame.MOUSEBUTTONDOWN:
                    position = pygame.mouse.get_pos()
                    self.model.activity[position] = 1

        pygame.quit()


def main():
    generator = AmariMazeGenerator((512, 512))
    generator.run()


if __name__ == "__main__":
    main()
29
user2432721

Le [:, :] représente tout, du début à la fin, tout comme les listes. La différence est que le premier : représente le premier et le second : pour la deuxième dimension.

a = numpy.zeros((3, 3))

In [132]: a
Out[132]: 
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

Affectation à la deuxième ligne:

In [133]: a[1, :] = 3

In [134]: a
Out[134]: 
array([[ 0.,  0.,  0.],
       [ 3.,  3.,  3.],
       [ 0.,  0.,  0.]])

Affectation à la deuxième colonne:

In [135]: a[:, 1] = 4

In [136]: a
Out[136]: 
array([[ 0.,  4.,  0.],
       [ 3.,  4.,  3.],
       [ 0.,  4.,  0.]])

Affecter à tous:

In [137]: a[:] = 10

In [138]: a
Out[138]: 
array([[ 10.,  10.,  10.],
       [ 10.,  10.,  10.],
       [ 10.,  10.,  10.]])
36
Mike Müller

numpy utilise des tuples comme index. Dans ce cas, il s'agit d'une affectation de tranche détaillée.

[0] 
#means line 0 of your matrix
[(0,0)] #means cell at 0,0 of your matrix
[0:1] #means lines 0 to 1 excluded of your matrix
[:1] #excluding the first value means all lines until line 1 excluded
[1:] #excluding the last param mean all lines starting form line 1 included
[:] #excluding both means all lines
[::2] #the addition of a second ':' is the sampling. (1 item every 2)
[::] #exluding it means a sampling of 1
[:,:] #simply uses a Tuple (a single , represents an empty Tuple) instead of an index.

C'est équivalent au plus simple

self.activity[:] = self.h

(qui fonctionne également pour les listes régulières)

14
njzk2

Il s'agit d'une affectation de tranche. Techniquement, il appelle1

self.activity.__setitem__((slice(None,None,None),slice(None,None,None)),self.h)

qui définit tous les éléments dans self.activity à n'importe quelle valeur self.h stocke. Le code que vous avez là semble vraiment redondant. Pour autant que je sache, vous pouvez supprimer l'ajout sur la ligne précédente, ou simplement utiliser l'affectation de tranche:

self.activity = numpy.zeros((512,512)) + self.h

ou

self.activity = numpy.zeros((512,512))
self.activity[:,:] = self.h

Le moyen le plus rapide est peut-être d'allouer un tableau vide et .fill avec la valeur attendue:

self.activity = numpy.empty((512,512))
self.activity.fill(self.h)

1Réellement, __setslice__ est tenté avant d'appeler __setitem__, mais __setslice__ est obsolète et ne devrait pas être utilisé dans le code moderne à moins que vous ayez une très bonne raison à cela.

11
mgilson