Решено: Вычисление среднего значения около numpy ошибка элемента массива: Ошибка типа: объект 'numpy .float64' не поддерживает назначение элемента - PullRequest
0 голосов
/ 15 апреля 2020

РЕДАКТИРОВАТЬ: я изменил мой код ниже, представляя рабочую версию, благодаря @ hpaulj

Я пытаюсь решить двумерное уравнение Лапласа с помощью итерации Гаусса-Зейделя: каждый не граничный элемент в матрице заменяется на среднее значение окружающих матричных элементов. Сначала я создаю матрицу basi c.

# creation of matrix using random values and boundary conditions.
matrix = np.random.random((4,4))
for n in range(4): matrix.itemset((4-1, n), 10)
for n in range(4): matrix.itemset((n, 4-1), 0)
for n in range(4): matrix.itemset((0, n), 0)
for n in range(4): matrix.itemset((n, 0), 0)

Вывод:

[[ 0.          0.          0.          0.        ]
 [ 0.          0.33285936  0.59830215  0.        ]
 [ 0.          0.07021714  0.45341002  0.        ]
 [ 0.         10.         10.          0.        ]]

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

# opening the matrix and preparing it to be read and rewritten.
#with np.nditer(matrix, op_flags=['readwrite']) as it:
with np.nditer(matrix, op_flags=['readwrite'], flags=['multi_index']) as it:

    # loop to find each element in our matrix
    #for index, x in np.ndenumerate(matrix):
    for x in it:
        #row, colum = index

        # only non-border values may be adjusted
        if x != 0 and x != 10:
            row, colum = it.multi_index

            # finding each element around x
            left = matrix[row][colum-1]
            right = matrix[row][colum+1]
            up = matrix[row-1][colum]
            down = matrix[row+1][colum]

            # finding average of elements around x
            newvalue = 1/4*(left+right+up+down)
            x[...] = newvalue

Вместо замены значений python выводит следующую ошибку:

x[...] = newvalue
TypeError: 'numpy.float64' object does not support item assignment

Я не получаю ошибку, если просто использую

for x in it:

но тогда я не могу отслеживать значения x, y в моем массиве. Кто-нибудь знает, как отслеживать положение элемента или устранить ошибку?

1 Ответ

1 голос
/ 15 апреля 2020

Лучше использовать индекс numpy для установки матрицы:

In [358]: arr = np.random.random((4,4))                                                                
In [359]: arr[[0,3],:] = 0                                                                             
In [360]: arr[:,[0,3]] = 0                                                                             
In [361]: arr[3,1:-1] = 10                                                                             
In [362]: arr                                                                                          
Out[362]: 
array([[ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.8869947 ,  0.61765067,  0.        ],
       [ 0.        ,  0.92640868,  0.83014953,  0.        ],
       [ 0.        , 10.        , 10.        ,  0.        ]])

или даже:

In [363]: arr = np.zeros((4,4))                                                                        
In [364]: arr[1:-1,1:-1] = np.random.random((4-2,4-2))                                                 
In [365]: arr                                                                                          
Out[365]: 
array([[0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.50803298, 0.78055366, 0.        ],
       [0.        , 0.98941105, 0.61842531, 0.        ],
       [0.        , 0.        , 0.        , 0.        ]])

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

Вот разница, о которой я упоминал в комментариях:

In [367]: with np.nditer(arr, op_flags=['readwrite']) as it: 
     ...:    for x in it: 
     ...:        print(type(x), x) 
     ...:                                                                                              
<class 'numpy.ndarray'> 0.0
<class 'numpy.ndarray'> 0.0
<class 'numpy.ndarray'> 0.0
...
In [368]: for index,x in np.ndenumerate(arr): 
     ...:     print(type(x),x) 
     ...:                                                                                              
<class 'numpy.float64'> 0.0
<class 'numpy.float64'> 0.0
<class 'numpy.float64'> 0.0
....

и использование multi_Index:

In [369]: with np.nditer(arr, op_flags=['readwrite'],flags=['multi_index']) as it: 
     ...:    for x in it: 
     ...:        print(type(x), x, it.multi_index) 
     ...:                                                                                              
<class 'numpy.ndarray'> 0.0 (0, 0)
...
<class 'numpy.ndarray'> 0.5080329836279988 (1, 1)
<class 'numpy.ndarray'> 0.7805536642151875 (1, 2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...