Перебор списков с периодическими граничными условиями и вычисление расстояний между элементами - PullRequest
0 голосов
/ 26 марта 2019

Я пытаюсь написать функцию 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...