Слишком много индексов для массива

Я пытаюсь создать 3D-изображение mat1 из данных, предоставленных мне объектом. Но я получаю ошибку для последней строки: mat1[x,y,z] = mat[x,y,z] + (R**2/U**2)**pf1[l,m,beta]:

IndexError: too many indices for array

В чем здесь может быть проблема?

Ниже приведен мой код:

mat1 = np.zeros((1024,1024,360),dtype=np.int32)

k = 498
gamma = 0.00774267
R = 0.37
g = np.zeros(1024)
g[0:512] = np.linspace(0,1,512)
g[513:] = np.linspace(1,0,511)
pf = np.zeros((1024,1024,360))
pf1 = np.zeros((1024,1024,360))

for b in range(0,1023) :
  for beta in range(0,359) :
    for a in range(0,1023) :
      pf[a,b,beta] = (R/(((R**2)+(a**2)+(b**2))**0.5))*mat[a,b,beta]
    pf1[:,b,beta] = np.convolve(pf[:,b,beta],g,'same')

for x in range(0,1023) :
  for y in range(0,1023) :
    for z in range(0,359) :
        for beta in range(0,359) :
         a = R*((-x*0.005)*(sin(beta)) + (y*0.005)*(cos(beta)))/(R+    (x*0.005)*(cos(beta))+(y*0.005)*(sin(beta)))
          b = z*R/(R+(x*0.005)*(cos(beta))+(y*0.005)*(sin(beta)))
          U = R+(x*0.005)*(cos(beta))+(y*0.005)*(sin(beta))
          l = math.trunc(a)
          m = math.trunc(b)
          if (0<=l<1024 and 0<=m<1024) : 
              mat1[x,y,z] = mat[x,y,z] + (R**2/U**2)**pf1[l,m,beta]

person Prakriti Kumari    schedule 26.10.2015    source источник


Ответы (1)


Строка, в которой вы выполняете свертку:

pf1 = np.convolve(pf[:,b,beta],g)

генерирует 1-мерный массив, а не 3-мерный, как ваш вызов в последней строке: pf1[l,m,beta]

Чтобы решить эту проблему, вы можете использовать:

pf1[:,b,beta] = np.convolve(pf[:,b,beta],g,'same')

и вам также нужно предопределить pf1:

pf1 = np.zeros((1024,1024,360))

Обратите внимание, что свертка f*g (np.convole(f,g)) обычно возвращает длину |f|+|g|-1. Однако если вы используете np.convolve с параметром 'same', он возвращает массив с максимальной длиной f или g (т. е. max(|f|,|g|)).

Редактировать. Кроме того, вы должны быть уверены, что размеры используемых вами матриц и индексов верны, например:

Вы определяете mat1 = np.zeros((100,100,100),dtype=np.int32), таким образом, матрицу 100x100x100, но в последней строке вы делаете mat1[x,y,z], где переменные x, y и z явно выходят за эти размеры. В этом случае они попадают в диапазон матрицы mat. Вероятно, вам нужно изменить размеры mat1 также на такие:

mat1 = np.zeros((1024,1024,360),dtype=np.int32)

Также убедитесь, что последние индексы переменных, которые вы вычисляете (l и m), находятся в пределах размерности pf1.

Изменить 2: функция range(a,b) возвращает массив от a до b, но не включая b. Например, вместо range(0,1023) вы должны написать range(0,1024) (или короче: range(1024)).

Изменить 3: чтобы проверить, превышают ли l или m размеры, вы можете добавить ошибку, как только они это сделают:

      l = math.trunc(a)
      if l>=1024:
          print 'l exceeded bounds: ',l
      m = math.trunc(b)
      if m>=1024:
          print 'm exceeded bounds: ',m

Редактировать 4: обратите внимание, что ваш код, особенно ваш последний for, займет много времени! Ваша последняя вложенность результатов за 1024*1024*360*360=135895449600 итераций. С небольшой оценкой времени, которую я сделал (рассчитывая время выполнения кода в вашем цикле for), ваш код может выполняться около 5 дней.

Небольшая простая оптимизация, которую вы могли бы сделать, это вместо того, чтобы несколько раз вычислять sin и cos, создать переменную, хранящую значение:

sinbeta = sin(beta)
cosbeta = cos(beta)

но это, вероятно, все еще займет несколько дней. Возможно, вы захотите проверить, как оптимизировать свои вычисления или вычислить их, например, с помощью программы на языке C.

person agold    schedule 26.10.2015
comment
Я пробовал pf1[:,b,beta] = np.convolve(pf[:,b,beta],g), но все равно выдает ту же ошибку. - person Prakriti Kumari; 28.10.2015
comment
Смотрите ответ, я изменил его. - person agold; 28.10.2015
comment
Спасибо! Я не получаю эту ошибку сейчас. Но теперь я получаю mat1[x,y,z] = mat[x,y,z] + (R2/U2)**pf1[l,m,beta] IndexError: index1024 выходит за пределы оси 1 с размером 1024 - person Prakriti Kumari; 29.10.2015
comment
Из ошибки я понимаю, что переменная l получает значение 1024, которое выходит за пределы допустимого, поскольку первое измерение pf1 имеет длину 1024 (т.е. имеет индекс от 0 до 1023). - person agold; 29.10.2015
comment
Даже когда я инициализирую: для x в диапазоне (0,1025) я получаю ту же ошибку. - person Prakriti Kumari; 30.10.2015
comment
Нет, вы не должны увеличивать диапазон x, если вы не меняете размеры матрицы. Смотрите редактирование в моем ответе. - person agold; 30.10.2015
comment
Да. Я изменил его на 1024 1024 360. Тем не менее, та же ошибка. Вы можете увидеть мой отредактированный код выше. - person Prakriti Kumari; 30.10.2015
comment
Вы проверили, не превышают ли переменные l и m размеры pf1? - person agold; 30.10.2015
comment
Когда я пытаюсь узнать len(l) или len(m), они говорят, что объект типа 'int' не имеет len(). Преобразуется ли он в целое число из-за усечения a и b? Я действительно хочу, чтобы в окончательном уравнении были только a и b. Но поскольку индексы должны быть целыми числами, отсюда и усечение. - person Prakriti Kumari; 30.10.2015
comment
l и m — скаляры, и я имел в виду их значения, которые не должны превышать размерности pf1, в данном случае 0‹=l,m‹1024. - person agold; 30.10.2015
comment
Когда я печатаю m и l, запускаются четыре цикла for, и я продолжаю получать значения l и m. Таким образом, имеется 1024*1024*360 значений каждого из l и m. И, следовательно, когда это не соответствует окончательному уравнению, поскольку размеры l и m должны быть только 1024. - person Prakriti Kumari; 30.10.2015
comment
Итак, я внес изменения в соответствии с вашим предложением (выше в коде), но теперь он работает с бесконечного времени без каких-либо ошибок или результатов. - person Prakriti Kumari; 02.11.2015