Как рекурсивно увеличить масштаб массива Numpy

#python #arrays #numpy #recursion #fractals

#python #массивы #numpy #рекурсия #фракталы

Вопрос:

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

 def zoom(array, max_zoom, zoom_level):
    half_width = int(array.shape[0]/2)
    half_height = int(array.shape[1]/2)
    print(array)

    while zoom_level < max_zoom:
        array = array[:half_width, :half_height]
        zoom_level  = 1
        zoom(array, max_zoom, zoom_level)
 

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

Например, zoom(array, 3, 0) должен выдавать результат ниже для сетки 8×8.

 [[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0.]] 

[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]

[[0. 0.]
[0. 0.]]

[[0.]]
 

Но вместо этого дает:

 [[0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0.]]
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
[[0. 0.]
 [0. 0.]]
[[0.]]
[[0. 0.]
 [0. 0.]]
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
[[0. 0.]
 [0. 0.]]
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
 

Может ли кто-нибудь пролить свет на то, почему эта функция плохо себя ведет?

Ответ №1:

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

 def zoom(array, max_zoom, zoom_level):
    print(array)
    if zoom_level < max_zoom:
        half_width = array.shape[0] // 2
        half_height = array.shape[1] // 2
        array = array[:half_width, :half_height]
        zoom_level  = 1
        zoom(array, max_zoom, zoom_level)

A = np.zeros((9, 9))

zoom(A, 3, 0)
 

Вывод будет:

 [[0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
[[0. 0.]
 [0. 0.]]
[[0.]]