2013-05-29 2 views
18

Извините за глупый вопрос. Я программирую на PHP, но нашел хороший код на Python и хочу «воссоздать» его на PHP. Но я очень расстроен по поводу линииЧто означает [:,:] для массивов NumPy

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

Но я не понимаю, что делает

[:, :] 

среднее.

Кроме того, я не смог «Google It».

Полный код

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() 
+0

Здесь 'self.activity [:,:] = self.h' избыточна потому что 'self.activity' уже' self.h'. Похоже на это: 'a = 0 + 2', а затем' a = 2'. Это не совсем то же самое, но может помочь понять. –

ответ

24

[:, :] означает все от начала до конца, как и для списков. Разница в том, что первый : означает первый и второй : для второго измерения.

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

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

Присвоение второй строке:

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

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

Назначение ко второму столбцу:

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

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

Назначение всем:

In [137]: a[:] = 10 

In [138]: a 
Out[138]: 
array([[ 10., 10., 10.], 
     [ 10., 10., 10.], 
     [ 10., 10., 10.]]) 
11

Это назначение ломтика. Технически, он называет

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

, который устанавливает все элементы в self.activity к тому, что значение self.h хранит. Код, который у вас там, действительно кажется излишним. Насколько я могу судить, вы можете удалить дополнение на предыдущей строке, или просто использовать назначение ломтика:

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

или

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

Возможно, самый быстрый способ сделать это, чтобы выделить пустой массив и .fill его с ожидаемым значением:

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

на самом деле, __setslice__ пытается позвонить __setitem__, но __setslice__ устарел и не должен использоваться в современном коде, если у вас нет по-настоящему веской причины для этого.

+0

проверьте этот http://stackoverflow.com/questions/509211/the-python-slice-notation –

+0

@ZangMingJie - Да, это канонический ответ для нотации фрагментов. однако большинство этих ответов (неявно) сосредоточено на '__getitem__', а не' __setitem__', поэтому я подумал, что было бы разумно повторно ответить с этой другой точки зрения. – mgilson

+0

Поэтому я могу предположить, что PHP-версия Python arr [:] + = 1 будет foreach ($ arr as $ k => $ v) {$ arr [$ k] + = 1; } Или, по крайней мере, близко к нему. – user2432721

7

NumPy использует кортежи в качестве индексов. В этом случае это подробное задание среза.

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

Это эквивалентно более простой

self.activity[:] = self.h 

(который также работает для обычных списков, а)

Смежные вопросы