Я пытаюсь написать функцию Python, которая принимает индекс списка в качестве входа n1
, затем в интервале размером w
выбирает [n1-w,n1+w]
выбирает другой индекс n2 с вероятностью, которая уменьшается как функция разделения между n1
и n2
и возвращает индекс n2
и элемент списка, соответствующий n2
.
В моей текущей реализации («Попытка 1») сначала я вычисляю все вероятности, используя, а затем выбираю индекс с весами.
Это прекрасно работает (я думаю), учитывая список [0,1,2,3,4,5,6,7,8,9]
и если мой n1
находится где-то посередине, скажем 5
и w=2
, то элемент выбирается из интервала
[3 4 5 6 7]
с весами вероятности [0.16666667 0.33333333 0. 0.33333333 0.16666667]
.
Проблема, с которой я сталкиваюсь, заключается в том, что если я выбираю элемент с концов, например, выбор n2choice(8)
дает
[6 7 8 9]#indices interval
[0.2 0.4 0. 0.4]#weights
Вместо этого я бы хотел интервал
[6 7 8 9 0]# indices interval
[0.16666667 0.33333333 0. 0.33333333 0.16666667]#weights
Или аналогично, на другом конце n2choice(1)
дает [0 1 2 3]#interval
[0.2 0.4 0. 0.4]#weights
Вместо этого я хотел бы получить
[9 0 1 2 3]# indices interval
[0.16666667 0.33333333 0. 0.33333333 0.16666667]#weights
По сути, я хотел бы преобразовать текущие «поглощающие» граничные условия, которые я реализовал, в «периодические границы», где список 1D фактически рассматривается как кольцо 1D.
Для этого я попытался использовать оператор %
(см. Попытку 2). Однако это выдает «IndexError: list index вне диапазона». Я мог бы использовать некоторую помощь в устранении неполадок в этом коде, а также предложить быстрый, питонский способ сделать это. Я хотел бы иметь возможность сделать это для массивов произвольной длины и с произвольным w вместо этого простого тестового примера, представленного здесь.
#Attempt 1
import numpy as np
import random
a = [0,1,2,3,4,5,6,7,8,9]
w =2
mylist = np.array(a)
indices_list = np.arange(mylist.size)
def n2choice(n1):
prob_wts = [0 if i+(n1-w) == n1 else 1/(abs(i+(n1-w)-n1))**(1.) for i in np.arange(mylist[max(n1-w,0):n1+w+1].size)]
prob_wts = np.array(prob_wts)/sum(prob_wts)
#for i in np.arange(mylist[max(n1-w,0):n1+w+1].size):
#print(i, i+(n1-w))
print(prob_wts)
print(sum(prob_wts))
print(indices_list[max(n1-w,0):n1+w+1])
n2 = random.choices(indices_list[max(n1-w,0):n1+w+1], weights=prob_wts,k=1)
print(prob_wts[max(n1-w,0):n1+w+1])
n2_c = (n2[0], mylist[n2[0]])
return np.array(n2_c)
n2choice(5)
#Attempt 2
import numpy as np
import random
import itertools
a = [0,1,2,3,4,5,6,7,8,9]
w =2
mylist = np.array(a)
indices_list = np.arange(mylist.size)
def n2choice(n1):
prob_wts = [0 if i+(n1-w) == n1 else 1/(abs(i+(n1-w)-n1))**(1.) for i in np.arange(mylist[(n1 - w)%len(mylist):(n1+w+1)%len(mylist)].size)]
prob_wts = np.array(prob_wts)/sum(prob_wts)
#for i in np.arange(mylist[max(n1-w,0):n1+w+1].size):
#print(i, i+(n1-w))
print(prob_wts)
print(sum(prob_wts))
print(indices_list[(n1 - w)%len(mylist):(n1+w+1)%len(mylist)])
n2 = random.choices(indices_list[(n1 - w)%len(mylist):(n1+w+1)%len(mylist)], weights=prob_wts,k=1)
#print(prob_wts[max(n1-w,0):n1+w+1])
n2_c = (n2[0], mylist[n2[0]])
return np.array(n2_c)
n2choice(1)