Есть ли способ конвертировать multi_index в строку int / list / array? - PullRequest
0 голосов
/ 24 мая 2019

Я хочу изменить значение данного массива в numpy для умножения других элементов массива.Поэтому я хочу извлечь multi_index и манипулировать им, чтобы я мог определить позицию и использовать ее.(например, пропустить через все элементы и всегда делать 'текущая позиция в массиве = следующая позиция + позиция выше в массиве'

Я попытался вызвать функцию с multi_index текущей позиции и хочу, чтобы указанная функция взяла его инапример, увеличить его на одну позицию. (<0, 1> ---> <0, 2>, в то время как <0, n> n> = длина в противном случае <0, 1> ---> <1, 0>)

import numpy as np;

def fill(multi_index):
    "This will get the new value of the current iteration value judgeing from its index"
    return a[(multi_index + <0,1>) + (multi_index + <0,-1>) + (multi_index + <1,0>) + (multi_index + <-1,0>)]

#a = np.random.uniform(0, 100, size=(100, 100))
a = np.arange(6).reshape(2,3)

it = np.nditer(a, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
    it[0] = fill(it.multi_index)
    print(it[0])
    it.iternext()

"""for x in np.nditer(a, flags=['multi_index'], op_flags=['readwrite']):

    print(x)"""

Я не понимаю, как извлечь фактические "координаты" из multi_index. Я немного новичок в python, поэтому, пожалуйста, постарайтесь объяснить это полностью, если это возможно. Спасибо.

Edit : Раньше я только программировал на C ++ и немного Java, поэтому я обычно использовал массивы (в c ++ это было бы примерно так:

int main() { 
  int a[100][100];
  for (int i=1, i<=a.length-1, i++) { 
    for (int j=1, i<=a.width-1, j++) { 
      a[i][j] = 1/4 (a[i][j+1]+a[i][j-1]+a[i+1][j]+a[i-1][j]);
    } 
  } 
return 0;
}

1 Ответ

0 голосов
/ 24 мая 2019
In [152]: a = np.arange(6).reshape(2,3)                                                                  
In [153]: a                                                                                              
Out[153]: 
array([[0, 1, 2],
       [3, 4, 5]])

Давайте запустим ваш nditer и посмотрим на его значения:

In [157]: it = np.nditer(a, flags=['multi_index'], op_flags=['readwrite'])                               
In [158]: while not it.finished: 
     ...:     print(it.multi_index, a[it.multi_index], it[0], type(it[0])) 
     ...:     it.iternext() 
     ...:                                                                                                
(0, 0) 0 0 <class 'numpy.ndarray'>
(0, 1) 1 1 <class 'numpy.ndarray'>
(0, 2) 2 2 <class 'numpy.ndarray'>
(1, 0) 3 3 <class 'numpy.ndarray'>
(1, 1) 4 4 <class 'numpy.ndarray'>
(1, 2) 5 5 <class 'numpy.ndarray'>

На каждой итерации multiindex является кортежем индексов i,j.a[it.multiindex] затем выбирает этот элемент из массива.Но it[0] также является этим элементом, но упакован в 0d массив.Если вас не устраивает идея массива 0d (форма ()), тогда nditer не является для вас инструментом (в настоящее время).

Если вы просто хотите использовать последовательные индексные кортежи,ndindex работает так же хорошо:

In [162]: list(np.ndindex(a.shape))                                                                      
Out[162]: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

(на самом деле, np.lib.index_tricks.py показывает, что ndindex использует nditer мультииндекс. nditer обычно не используется в numpy уровне Pythonкод.)

Или получить индексы плюс значение:

In [177]: list(np.ndenumerate(a))                                                                        
Out[177]: [((0, 0), 0), ((0, 1), 1), ((0, 2), 2), ((1, 0), 3), ((1, 1), 4), ((1, 2), 5)]

Просто значения в плоском порядке:

In [178]: a.ravel()                                                                                      
Out[178]: array([0, 1, 2, 3, 4, 5])

НО, в numpy мы предпочитаем неповторять вообще.Вместо этого мы пытаемся написать код, который работает со всем массивом, используя быстро скомпилированные numpy методы.Итерация для массивов медленная, медленнее, чем итерация для списков.

===

Похоже, ваша итерация в несколько стилизованном смысле:

for i in range(n):
    for j in range(m):
         a[i,j] = ( a[i,j+1] + a[i,j-1] + a[i+1,j] + a[i-1,j] )/4 

Тамнекоторые детали, о которых нужно беспокоиться.Как насчет краев, где j+/-1 выходит за границы?И является ли этот расчет последовательным, так что a[i,j] зависит от только что внесенных изменений в a[i,j-1];или это буферизовано?

В общем случае последовательные итерационные вычисления для такого массива плохо подходят для numpy.

С другой стороны, буферизованные вычисления могут быть хорошо выполнены с целымисрезы массива

x[1:-1, 1:-1] = (x[:,:-1]+x[:,1:]+x[:-1,:]+x[1:,:])/4

В scipy также есть некоторые функции свертки, которые выполняют вычисления на движущихся окнах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...