Есть ли способ конвертировать multi_index в строку int / list / array?
Я хочу изменить значение данного массива в numpy для умножения других элементов массива. Поэтому я хочу извлечь multi_index и манипулировать им, чтобы я мог определить позицию и использовать ее. (например, nditer через все элементы и всегда делать 'текущая позиция в массиве = следующая позиция + позиция выше в массиве'
Я попытался вызвать функцию с 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, поэтому, пожалуйста, постарайтесь объяснить это полностью, если это возможно. Благодарю.
Редактировать: Раньше я только программировал на 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 ответ
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
некоторые функции свертки, которые выполняют вычисления на движущихся окнах.