Расширение массива путем повторения значений, если другой массив не продолжается - PullRequest
0 голосов
/ 28 августа 2018

Я отслеживаю некоторые частицы на плоской поверхности с помощью плагина TrackPy. Это приводит к кадру данных с позициями в x и y и соответствующему номеру кадра, который здесь показан простым списком:

x=[80.1,80.2,80.1,80.2,80.3]
y=[40.1,40.2,40.1,40.2,40.3]
frame = [1,2,3,4,5]

Однако из-за экспериментальной установки частицу можно потерять за один кадр, что приведет к:

x=[80.1,80.2,80.1,80.2,80.3]
y=[40.1,40.2,40.1,40.2,40.3]
frame = [1,2,3,4,6]

Теперь я хотел бы расширить весь список, чтобы «кадр» продолжался, а «x, y» будет повторять предыдущее значение, если в исходных данных нет кадра, что приведет к чему-то вроде:

x=[80.1,80.2,80.1,80.2,80,2,80.3]
y=[40.1,40.2,40.1,40.2,40.2,40.3]
frame = [1,2,3,4,5,6]

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Вот одно решение на основе NumPy -

def extend_arrs(x,y,frame):
    # Convert to arrays
    frame = np.asarray(frame)
    x = np.asarray(x)
    y = np.asarray(y)

    l = frame[-1]-frame[0] + 1
    id_ar = np.zeros(l,dtype=int)
    id_ar[frame-frame[0]] = 1
    idx = id_ar.cumsum()-1
    return np.r_[frame[0]:frame[-1]+1],x[idx], y[idx]

Пробный прогон -

In [164]: x
Out[164]: [80.1, 80.2, 80.1, 80.2, 80.3]

In [165]: y
Out[165]: [40.1, 40.2, 40.1, 40.2, 40.3]

In [166]: frame = [5,6,8,11,13]

In [167]: extend_arrs(x,y,frame)
Out[167]: 
(array([ 5,  6,  7,  8,  9, 10, 11, 12, 13]),
 array([80.1, 80.2, 80.2, 80.1, 80.1, 80.1, 80.2, 80.2, 80.3]),
 array([40.1, 40.2, 40.2, 40.1, 40.1, 40.1, 40.2, 40.2, 40.3]))

# Output in tabular format for quick reference
In [168]: np.c_[extend_arrs(x,y,frame)]
Out[168]: 
array([[ 5. , 80.1, 40.1],
       [ 6. , 80.2, 40.2],
       [ 7. , 80.2, 40.2],
       [ 8. , 80.1, 40.1],
       [ 9. , 80.1, 40.1],
       [10. , 80.1, 40.1],
       [11. , 80.2, 40.2],
       [12. , 80.2, 40.2],
       [13. , 80.3, 40.3]])
0 голосов
/ 28 августа 2018

Numpy и diff

Используйте diff, чтобы определить, сколько раз нам нужно повторить.

Функция

def ext_pir(x, y, frame):
  x, y, frame = map(np.asarray, [x, y, frame])

  mn, mx = frame.min(), frame.max() + 1
  d = np.diff(np.append(frame, mx))
  r = np.arange(len(frame))
  i = r.repeat(d)

  return x[i], y[i], np.arange(mn, mx)

Демонстрация

x = [80.1, 80.2, 80.1, 80.2, 80.3]
y = [40.1, 40.2, 40.1, 40.2, 40.3]

frame = [1, 2, 3, 4, 6]

print("Inputs")
print(*map(np.asarray, (x, y, frame)), sep='\n')
print()
print("Outputs")
print(*ext_pir(x, y, frame), sep='\n')

Inputs
[80.1 80.2 80.1 80.2 80.3]
[40.1 40.2 40.1 40.2 40.3]
[1 2 3 4 6]

Outputs
[80.1 80.2 80.1 80.2 80.2 80.3]
[40.1 40.2 40.1 40.2 40.2 40.3]
[1 2 3 4 5 6]

x = [80.1, 80.2, 80.1, 80.2, 80.3]
y = [40.1, 40.2, 40.1, 40.2, 40.3]

frame = [5, 6, 8, 11, 13]

print("Inputs")
print(*map(np.asarray, (x, y, frame)), sep='\n')
print()
print("Outputs")
print(*ext_pir(x, y, frame), sep='\n')

Inputs
[80.1 80.2 80.1 80.2 80.3]
[40.1 40.2 40.1 40.2 40.3]
[ 5  6  8 11 13]

Outputs
[80.1 80.2 80.2 80.1 80.1 80.1 80.2 80.2 80.3]
[40.1 40.2 40.2 40.1 40.1 40.1 40.2 40.2 40.3]
[ 5  6  7  8  9 10 11 12 13]
0 голосов
/ 28 августа 2018

Вы можете использовать панд, которые внутренне используют массивы NumPy:

import pandas as pd

df = pd.DataFrame({'x': x, 'y': y}, index=frame)

df = df.reindex(np.arange(df.index.min(), df.index.max()+1)).ffill()

Результат

print(df)

      x     y
1  80.1  40.1
2  80.2  40.2
3  80.1  40.1
4  80.2  40.2
5  80.2  40.2
6  80.3  40.3

Затем вы можете извлечь свой результат в списки:

x = df['x'].tolist()
y = df['y'].tolist()
frame = df.index.tolist()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...