Во-первых, давайте разберем ваш код раздел за разделом ... Есть несколько проблем с тем, что вы написали сейчас ...
Между прочим, в python есть свободное соглашение о резервировании имен в верхнем регистре и CamelCasedдля занятий.(Вы часто будете видеть код вроде foo = FooBar(baz)
, где foo
- это экземпляр класса FooBar
.) Нет ничего плохого в том, чтобы вызывать вашу переменную Converted
вместо converted
, но большинство кода вы увидитебудет использовать последнюю форму.
Итак, начнем здесь:
import numpy as np
def grid(array,samples,details):
...
Похоже, вы передаете список как array
позже.Из-за этого вам необходимо преобразовать список array
в numpy.ndarray
.(В противном случае такие вещи, как array.reshape
не будут работать.) Вы можете также рассмотреть возможность изменения имени переменной на более менее общее, чем "array
".Однако на данный момент давайте сохраним имена переменных одинаковыми.Я также собираюсь предположить, что вам нужны значения с плавающей запятой, поскольку вы умножаете на проценты позже ... Давайте изменим это на:
import numpy as np
def grid(array,samples,details):
array = np.asarray(array, dtype=np.float)
...
Двигаемся дальше ...
...
#Sides of the square (will be using a squarable number
Width = (len(array)) ** 0.5
#Convert to grid
Converted = array.reshape(Width,Width)
...
У вас там математическая задача !!Массив 2x2 как 4 элемента, массив 3x3 имеет 9, массив 4x4 будет иметь 16 и т. Д. Если вы хотите преобразовать последовательность в квадратную сетку, вам нужно взять квадратный корень, а не делить на 2!Давайте изменим это на:
...
#Sides of the square (will be using a squareable number)
Width = int(np.sqrt(array.size))
#Convert to grid
Converted = array.reshape(Width,Width)
...
Во всем виноват недостаток сна ... Понятно, что x**0.5
- это то же самое, что и sqrt(x)
, я просто не видел второе *
.Извините за это!
Далее:
...
Change = [details[1]] + [details[2]]
...
Это то же самое, что просто сделать это:
Change = details[1:3]
Часть после этого в порядке, поэтому давайте перейдем кк следующей проблеме:
...
#Set the value within a 3x3 window to their "new_value"
for elem in Converted[istart:istop, jstart:jstop]:
Converted[elem] = elem + (elem * (value * ((Change[1]/100))
#Set the main value to the new value
Converted[i,j] = value + (value * ((Change[0])/100))
...
Прежде всего, когда вы выполняете итерацию, elem
- это значение , а не index !Вы не можете индексировать массив по полученным значениям, иначе вы бы пытались индексировать его по таким вещам, как 0.01
, pi
или, возможно, даже по сложным числам, таким как 5.6 + 98.44j
.Во-вторых, вы используете numpy по какой-то причине ... Нет причин повторять каждый элемент, как этот.В-третьих, вы меняете значение центра дважды, что почти не соответствует вашим ожиданиям.Вместо этого мы можем просто сделать это:
...
#--Set the value within a 3x3 window to their "new_value"
# Save the "center" value for later use
center = Converted[i,j]
# Adjust the pixels around the center by a percentage
Converted[istart:istop] *= 1 + Change[1] / 100.0
# Adjust the center pixel by a different percentage
Converted[i,j] = center * (1 + Change[0] / 100.0)
...
Наконец, у вас есть проблема с длиной списка "array
", который вы передаете ...
a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19,20,21,22,23,24,25]
Это массив из 31 элемента ... Невозможно создать этот квадрат без усечения или добавления значений.Ваш текущий код попытается превратить его в массив 15x15, что приведет к ошибке (матрица 15x15 потребует 255 значений (15**2
)).Я собираюсь предположить, что вы хотели вместо этого 25-элементный массив 5x5.Давайте заменим это на:
a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19]
Хорошо, так что давайте соединим все эти предложения в работающий кусок кода:
import numpy as np
def grid(array,samples,details):
array = np.asarray(array, dtype=np.float)
#Sides of the square (will be using a squarable number
Width = int(np.sqrt(array.size))
#Convert to grid
Converted = array.reshape(Width,Width)
#Conversion details
Change = details[1:3]
nrows, ncols = Converted.shape
for value in samples:
#First instance where indexing returns it
i,j = np.argwhere(Converted == value)[0]
#Prevent indexing outside the boudaries of the
#array which would cause a "wraparound" assignment
istart, istop = max(i-1, 0), min(i+2, nrows)
jstart, jstop = max(j-1, 0), min(j+2, ncols)
#Set the value within a 3x3 window to their "new_value"
center_value = Converted[i,j]
Converted[istart:istop, jstart:jstop] *= 1 + Change[1] / 100.0
Converted[i,j] = center_value * (1 + Change[0] / 100.0)
#Convert back to 1D list
Converted.tolist()
return Converted
a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19]
samples = [2, 7]
grid_details = [10,50,100]
result = grid(a,samples,grid_details)
print(result)
Итак, это преобразует ваш исходный массив:
[[ 16. 2. 20. 4. 14.]
[ 6. 70. 8. 9. 100.]
[ 32. 15. 7. 14. 50.]
[ 20. 17. 10. 9. 20.]
[ 7. 17. 50. 2. 19.]]
В:
[[ 32. 3. 40. 4. 14. ]
[ 12. 280. 32. 18. 100. ]
[ 32. 30. 10.5 28. 50. ]
[ 20. 34. 20. 18. 20. ]
[ 7. 17. 50. 2. 19. ]]
Хорошо.Теперь то, о чем я думаю, вы изначально просили ... В этом случае элемент во втором ряду, второй столбец изменяется дважды ... Один раз из-за 2 в первом ряду, второй столбец, и один раз из-за 7в третьем ряду, третий столбец.
Это то, что вы хотели избежать ??Если да, что вы хотите, чтобы произошло в этом случае?
Хотите ли вы, чтобы он был изменен только к первому совпадению?Второй матч?Модифицировано оба раза, но изменилось ли это только суммой процентов?Вам нужно определить, что вы хотите, чтобы это произошло.
В любом случае, надеюсь, это поможет!
Редактировать
Если вы хотите избежать соответствияНедавно измененное значение, вы можете просто найти все совпадения, прежде чем начинать изменять вещи.Например, если мы изменим эту часть:
for value in samples:
#First instance where indexing returns it
i,j = np.argwhere(Converted == value)[0]
На это:
locations = [np.argwhere(Converted == value)[0] for value in samples]
for i,j in locations:
...
Он должен делать то, что вы хотите.Надеюсь, это понятно!