Среднее значение столбца на основе интервалов второго столбца - PullRequest
1 голос
/ 31 марта 2020

У меня есть набор данных, который имеет два столбца, столбец 1 - это время, которое длится от 1 до 9 секунд, а столбец 2 - вероятность события в определенную c секунду со значениями 30, 69, 56, 70. , 90, 59, 87, 10, 20.

Я пытаюсь получить среднюю вероятность за интервал времени (через 2 секунды для этого случая), например, вероятность от 2 до 3 секунд, от 2 до 4 секунд, от 2 до 5 секунд, .... от 2 до 9 секунд.

Я попробовал следующий подход, где я определил функцию t_inc с шагом 1 больше 2. Однако я получаю следующее сообщение об ошибке (P_slice_avg_1 в коде):

Невозможно передать операнды вместе с фигурами (9,) (7,)

, потому что мой t_in c имеет форму 7.

Когда я попытался сделать это вручную (P_slice_avg_2 в коде), это работает, но не осуществимо, если я хочу сделать это в течение огромного количества интервалов.

Любая помощь в том, как ее обобщить, была бы очень полезной.

import numpy as np
data=np.loadtxt('C:/Users/Hrihaan/Desktop/Sample.txt')

t=data[:,0] # t goes from 1 to 9
P=data[:,1] # probability of an event in a specific second

i= np.arange(1, 8 , 1)
t_inc= 2 + i 

P_slice_avg_1= np.mean(P[(t>=2) & (t<=t_inc)]) # I thought this would give me the averages between 2 and values of t_inc

P_slice_avg_2= np.mean(P[(t>=2) & (t<=3)]), np.mean(P[(t>=2) & (t<=4)]), np.mean(P[(t>=2) & (t<=5)]), np.mean(P[(t>=2) & (t<=6)]), np.mean(P[(t>=2) & (t<=7)]), np.mean(P[(t>=2) & (t<=8)]), np.mean(P[(t>=2) & (t<=9)])

1 Ответ

1 голос
/ 31 марта 2020

Здесь векторизованный подход, использующий numpy вещание :

import numpy as np
t = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) 
P = np.array([30, 69, 56, 70, 90, 59, 87, 10, 20], dtype=float) 
i = np.arange(1, 8 , 1)
t_inc= 2 + i 

T = np.tile(t[:,None], len(i))
P = np.tile(P[:,None], len(i))

np.tile создает массив, повторяя его количество заданных раз, в в этом случае у нас будет len(i) копий t и P, а именно:

P
array([[30., 30., 30., 30., 30., 30., 30.],
       [69., 69., 69., 69., 69., 69., 69.],
       [56., 56., 56., 56., 56., 56., 56.],
       [70., 70., 70., 70., 70., 70., 70.],
       [90., 90., 90., 90., 90., 90., 90.],
       [59., 59., 59., 59., 59., 59., 59.],
       [87., 87., 87., 87., 87., 87., 87.],
       [10., 10., 10., 10., 10., 10., 10.],
       [20., 20., 20., 20., 20., 20., 20.]])

Теперь мы обнуляем все элементы, не удовлетворяющие требуемому условию, используя np.logical_or :

P[np.logical_or(2>T, T>t_inc)]=0
P
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [69., 69., 69., 69., 69., 69., 69.],
       [56., 56., 56., 56., 56., 56., 56.],
       [ 0., 70., 70., 70., 70., 70., 70.],
       [ 0.,  0., 90., 90., 90., 90., 90.],
       [ 0.,  0.,  0., 59., 59., 59., 59.],
       [ 0.,  0.,  0.,  0., 87., 87., 87.],
       [ 0.,  0.,  0.,  0.,  0., 10., 10.],
       [ 0.,  0.,  0.,  0.,  0.,  0., 20.]])

Таким образом, мы храним в каждом столбце только элементы для усреднения, однако использование np.mean приведет к неверному результату, поскольку знаменатель будет P.shape[0], т.е. нулевые элементы. В качестве обходного пути мы можем суммировать вдоль оси и разделить на общее количество ненулевых элементов, используя np.count_nonzero:

np.sum(P, axis=0)/np.count_nonzero(P, axis=0)
array([62.5, 65., 71.25, 68.8, 71.83333333, 63., 57.625])
...