Массив Numpy, сравнивающий 2 массива по элементам с возрастающим смещением признаков
Здесь приведена версия проблемы случайного блуждания с использованием только пустых массивов. Чтобы найти время пересмотра позиции за 500 шагов, мы должны сравнить отсортированный массив позиций с его смещением, записать время, когда оно близко к 0, а затем увеличить смещение.
Вот мой код, проблема в цикле while, где я пытаюсь сохранить конечное количество раз, когда позиция пересматривается как элементы в zeroArray
Когда я запускаю его, я получаю ошибку индекса, результаты не записываются и счетчик, который многократно повторяется многократно, даже если булево выражение для остановки цикла изменилось.
редактировать: Как найти повторяющуюся позицию с массивом numpy: 1) отсортировать массив окончательной позиции в порядке возрастания. 2) Сравните срезы с увеличивающимися смещениями, если вы найдете позиции в пределах 0,001 м с этим смещением, то есть вы сравниваете позиции с соседними позициями (смещение 1). Вы можете найти 18 случаев, когда соседи считают, что в двух местах вы можете найти только 2 случая. И в трех местах вы найдете 0, в котором вы остановитесь.
import numpy as np
import random
MAX_STEP_SIZE = 0.90 # maximum size of a single step [m]
NUM_STEPS = 500 # number of steps in a random walk []
NUM_WALKS = 10 # number of random walks in a run []
TOLERANCE = 0.001 # separation of points considered the same [m]
STEP_TO_RECORD_1 = 100 # first step to record and analyze []
STEP_TO_RECORD_2 = 500 # 2nd step to record and analyze []
random.seed(12345)
#......................................................................distance
def distance(posA, posB) :
"""Distance between two positions"""
return np.abs(posA - posB)
#...............................................................initialPosition
def initialPosition() :
"""Initial position of walker at the start of a random walk"""
return 0.0
def genPositions(nSteps, maxStep) :
"""Return the new position after a random step between -maxStep and
maxStep, given the previous position"""
genArray1 = (maxStep - (-maxStep))*(np.random.random(nSteps+1)) + (-maxStep)
genArray1[0]=initialPosition()
return np.cumsum(genArray1)
oneStep = np.zeros(NUM_WALKS)
fiveStep = np.zeros(NUM_WALKS)
zeroStep = np.zeros(NUM_WALKS)
walkArray = np.zeros(NUM_WALKS)
counter = 1
hitcounter = 0
zerocounter = 0
keepchecking = bool(1)
for ii in range(NUM_WALKS):
position = (genPositions(NUM_STEPS, MAX_STEP_SIZE))
oneStep[ii] = position[100]
fiveStep[ii] = position[-1]
zeroArray = np.sort(position)
while keepchecking == bool(1):
zerocounter = 0
for jj in range(len(zeroArray)):
hitcounter = 0
if distance(zeroArray[jj+counter], zeroArray[jj]) <= TOLERANCE:
hitcounter +=1
zerocounter += hitcounter
counter +=1
if hitcounter == 0:
keepchecking = bool(0)
zeroStep[ii] = zerocounter
Спасибо за любую помощь,
1 ответ
Вы можете сделать прямое сравнение вектора ваших позиций с самим собой как:
deltas = np.abs(position[None, :] - position[:, None])
Сейчас, deltas[i, j]
расстояние между позициями на шаге i
и шаг j
, Вы можете получить свои хиты как:
hits = deltas <= TOLERANCE
Чтобы получить пары близких позиций, вы можете сделать следующее:
row, col = np.nonzero(hits)
idx = row < col # get rid of the diagonal and the upper triangular part
row = row[idx]
col = col[idx]
В качестве примера:
>>> position = genPositions(NUM_STEPS, MAX_STEP_SIZE)
>>> row, col = np.nonzero(np.abs(position[None, :] -
... position[:, None]) < TOLERANCE)
>>> idx = row < col
>>> row= row[idx]
>>> col = col[idx]
>>> row
array([ 35, 40, 112, 162, 165, 166, 180, 182, 200, 233, 234, 252, 253,
320, 323, 325, 354, 355, 385, 432, 443, 451], dtype=int64)
>>> col
array([ 64, 78, 115, 240, 392, 246, 334, 430, 463, 366, 413, 401, 315,
380, 365, 348, 438, 435, 401, 483, 473, 492], dtype=int64)
>>> for j in xrange(len(row)) :
... print '{0}, {1} --> {2}, {3}'.format(row[j], col[j], position[row[j]],
... position[col[j]])
...
35, 64 --> 2.56179226445, 2.56275159205
40, 78 --> 2.97310455111, 2.97247314695
112, 115 --> 3.40413767436, 3.40420856824
...
432, 483 --> 10.2560778101, 10.2556475598
443, 473 --> 10.7463713139, 10.7460626764
451, 492 --> 12.3804383241, 12.3805940238