2013-06-13 2 views
1

У меня проблема с поплавками на моих массивах.Массивы на Python с numpy

import numpy 
from StringIO import StringIO 


matrizgeometrica = numpy.loadtxt('geometrica.txt') # crea la matriz geometrica a partir del txt 
matrizvelocidades = numpy.loadtxt('velocidades.txt') # crea la matriz de velocidades a partir del txt 

#Se genera la matriz de tiempos unitarios a partir de la matriz geometrica y la matriz de velocidades 
matriztiempo=matrizgeometrica 
for x in matriztiempo: 
    for y in matriztiempo: 
     if matriztiempo[x,y]!=0 and matrizvelocidades[x,y]!=0: 
      matriztiempo[x,y]=matriztiempo[x,y]/matrizvelocidades[x,y] 
     else: 
      matriztiempo[x,y]=0 

ошибка заключается в следующем:

Traceback (most recent call last): 
    File "lpi2.py", line 12, in <module> 
    if matriztiempo[x,y]!=0 and matrizvelocidades[x,y]!=0: 
IndexError: arrays used as indices must be of integer (or boolean) type 

Я не знаю, в чем проблема, но я не могу изменить значения в целое, мне нужно поплавки.

+1

Какая форма являются матрицами? Я предполагаю, что 'for x in matriztiempo' оставляет вас с' x', который является массивом, а не целым числом ... – mgilson

ответ

4

Это ваш цикл:

for x in matriztiempo: 

Это установит x для значений из массива. Это не определяет положение значений; он просто получает значения.

Если вы хотите знать позицию, лучший способ заключается в использовании enumerate() так:

for i, x in enumerate(matriztiempo): 

Теперь x получает значение, как и раньше, но и i получает индекс этого значения в списке.

Я думаю, в вашем случае это может быть проще написать цикл, как это:

for x in xrange(matriztiempo.shape[0]): 
    for y in xrange(matriztiempo.shape[1]): 
     if matrizvelocidades[x,y] != 0: 
      matriztiempo[x,y] /= matrizvelocidades[x,y] 
     else: 
      matriztiempo[x,y] = 0 

Обычно в Python, когда мы работаем с двумя списками мы могли бы использовать zip() или itertools.izip(), чтобы получить значение, но в этом случае вы переписываете массив на месте с использованием двух значений индекса, и я думаю, что написать его выше, может быть, лучше. Конечно, это самое простое.

Обратите внимание, что нам не нужно проверять, что matriztiempo[x,y] равен нулю; если это так, то результат будет равен нулю для любого действительного делителя. Нам нужно проверить, что делитель действителен, чтобы исключить исключение из-за нуля. (Мы могли бы также поставить try:/except блок, чтобы поймать этот случай, если нуль является маловероятным значение в matrizvelocidades Если это вероятное значение, это хороший способ пойти

EDIT:.. Но так как это NumPy . есть лучший способ сделать это гораздо быстрее, если нам не нужно беспокоиться о нулях в делителе, мы могли бы просто сделать это:

matriztiempo /= matrizvelocidades 

Поскольку нам нужно беспокоиться о нулях, мы можем сделайте «маску», чтобы решить эту проблему.

good_mask = (matrizvelocidades != 0) 
bad_mask = numpy.logical_not(good_mask) 

matriztiempo[good_mask] /= matrizvelocidades[good_mask] 
matriztiempo[bad_mask] = 0.0 

Это должно быть значительно быстрее, чем решение, используя петли for.

Вы также мог бы сделать bad_mask так:

bad_mask = (matrizvelocidades == 0) 

Но явно вычисляя numpy.logical_not() мы уверены, что bad_mask всегда правильный логическим обратная good_mask. Если кто-то редактирует строку, которая создает good_mask, то numpy.logical_not() найдет правильный обратный, но если бы у нас было только второе выражение, ссылающееся на matrizvelocidades, то редактирование одного, но не редактирование другого, приведет к ошибке.

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