Сложная проблема нарезки Python / Numpy

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

Скажем, у нас есть простой массив, подобный этому:

a = array([1, 0, 0, 0])

Я хотел бы обновить последовательные записи в массиве (двигаясь слева направо) предыдущей записью из массива, используя синтаксис, подобный следующему:

a[1:] = a[0:3]

Это получит следующий результат:

a = array([1, 1, 1, 1])

Или как то так:

a[1:] = 2*a[:3]
# a = [1,2,4,8]

Чтобы проиллюстрировать далее, я хочу следующий вид поведения:

for i in range(len(a)):
    if i == 0 or i+1 == len(a): continue
    a[i+1] = a[i]

За исключением того, что я хочу скорость NumPy.

Поведение numpy по умолчанию - взять копию среза, так что я на самом деле получаю следующее:

a = array([1, 1, 0, 0])

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

Я сплю или это волшебство возможно?

Обновление: это все потому, что я пытаюсь использовать итерацию Гаусса-Зейделя для решения задачи линейной алгебры, более или менее. Это особый случай, связанный с гармоническими функциями, я старался не вдаваться в это, потому что это действительно не нужно и, вероятно, может еще больше запутать ситуацию, но здесь все в порядке.

Алгоритм такой:

while not converged:
    for i in range(len(u[:,0])):
        for j in range(len(u[0,:])):
            # skip over boundary entries, i,j == 0 or len(u)
            u[i,j] = 0.25*(u[i-1,j] + u[i+1,j] + u[i, j-1] + u[i,j+1])

Правильно? Но вы можете сделать это двумя способами: Jacobi включает в себя обновление каждого элемента со своими соседями без учета обновлений, которые вы уже сделали до цикла циклов while, чтобы сделать это в циклах, вы должны скопировать массив, а затем обновить один массив из скопированного массива. Однако Gauss-Seidel использует информацию, которую вы уже обновили, для каждой записи i-1 и j-1, поэтому нет необходимости в копировании, цикл должен по существу 'знать» так как массив был переоценен после каждого отдельного обновления элемента. То есть, каждый раз, когда мы вызываем запись типа u [i-1, j] или u [i, j-1], информация, вычисленная в предыдущем цикле, будет там.

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

u[1:-1,1:-1] = 0.25(u[:-2,1:-1] + u[2:,1:-1] + u[1:-1,:-2] + u[1:-1,2:])

Но результатом является итерация Якоби, потому что, когда вы берете фрагмент: u [:, - 2,1: -1] вы копируете данные, таким образом, фрагмент не знает о каких-либо сделанных обновлениях. Теперь NumPy все еще петли не так ли? Это не параллель, это просто более быстрый способ зацикливания, который выглядит как параллельная операция в python. Я хочу использовать это поведение путем своего рода взлома, чтобы вернуть указатель вместо копии, когда я беру часть. Правильно? Тогда каждый раз, когда петли NumPy, этот кусок будетОбновить' или просто повторить то, что произошло в обновлении. Для этого мне нужны кусочки с обеих сторон массива, чтобы быть указателями.

Во всяком случае, если есть какой-то действительно умный человек, который потрясающий, но яМы почти смирились с тем, что верим, что единственный ответ - зациклить на C.

Ответы на вопрос(9)

Ваш ответ на вопрос