Как вычислить «время удвоения» дискретных временных рядов, используя Pandas или Numpy? - PullRequest
1 голос
/ 05 апреля 2020

Вот набор данных. Каждая строка является отрезком времени. Первый столбец - это чтение. Второй - сколько отрезков времени на go показание составило 50% от того, что было. Я вычислил его вручную, сглаживая, чтобы числа были не совсем правильными.

197 
218 
256 
328     4
413     4
525     4
646     4
777     5
1159    4
1838    2
2417    2
3240    2.5
4257    3
4955    4
5752    5.5
6620    5
7738    5.5
8966    4.5
10402   5

Итак, предположим, что у меня есть DataFrame следующим образом:

df = pd.DataFrame({'val': [197,218,256,328,413,525,646,777,1159,1838,2417,3240,4257,4955,5752,6620,7738,8966,10402]})

Как бы я вычислил df .doubling? Я могу себе представить, что начинаю с конца и работаю задом наперед, каждый раз сканируя значение 50% от моего начального значения. Но есть и лучший способ. Я думаю, что это связано с Log2, но не уверен, как это сделать!

Ответы [ 3 ]

1 голос
/ 05 апреля 2020

Вы работаете над временем удвоения инфекций Covid-19?

Пожалуйста, внимательно проверьте результаты.

Я забыл, что вы используете Pandas, так что вы можете сначала это нужно:

y = df['val'].to_numpy()

Это первый выстрел:

import numpy as np
from scipy.interpolate import interp1d

y = np.array([197, 218, 256, 328, 413,525, 646, 646, 777,
              1159, 1838, 2417, 3240, 4257, 4955, 4955,
              5752, 6620, 7738, 8966, 10402],
              dtype=float)

# get the deltas to check if there was no increase
# between two consecutive data points        
dy = np.diff(y)

# these are the places without increase
idx = np.argwhere(dy) #could also be np.where(dy == 0.0)[0]

y_fixed = y.copy()

# create the x axis, probably days 
x = np.arange(y.shape[0])

# Hack: increase the second identical value be a
# small amount so the interpolation works
# increase the indices by one to increment the second value
y_fixed[idx + 1] += 0.001

# you need scipy > 0.17 for extrapolation to work
f = interp1d(y_fixed, x, fill_value="extrapolate")

# there are the values you need?
y_half = y / 2.0

# get the according x values by interpolation
x_interp = f(y_half)

# delta between the current day and the date when
# the value was half
dbl = x - x_interp

# this already looks quite good, but double check!
print(dbl)

Возможно, необходимо сместить ось x. Или, может быть, это все-таки правильно. Я подумаю об этом завтра со свободным sh мозгом.

enter image description here

На следующем изображении показаны оба алгоритма с вычисленными экспоненциальными данными, где две позиции где установлены не увеличивающиеся значения.

enter image description here

0 голосов
/ 06 апреля 2020

Возможно, в конечном итоге это будет выглядеть примерно так.

ACCURACY = 0

cases = [197, 218, 256, 328, 413,525, 646, 646, 777,
          1159, 1838, 2417, 3240, 4257, 4955, 4955,
          5752, 6620, 7738, 8966, 10402]
doubling = []

for t in range(len(cases)):
    found = False
    for t_2 in range(t):
        if cases[t_2] - (cases[t] // 2) > ACCURACY:
            doubling.append(t - t_2)
            found = True
            break

    # Append nothing if value not found
    if not found:
        doubling.append(None)
0 голосов
/ 05 апреля 2020

@ Джо, да, я работаю с этими данными. Вот решение старой школы. Я проследил за твоим решением и не смог его понять. Но мой не такой элегантный, но я думаю это правильно ... И график выглядит очень похоже на ваш ...!

import numpy as np
readings = np.array([197, 218, 256, 328, 413,525, 646, 646, 777,
          1159, 1838, 2417, 3240, 4257, 4955, 4955,
          5752, 6620, 7738, 8966, 10402],
          dtype=float)   

readingsLength = len(readings)
double = np.zeros(readingsLength)
for i in range( readingsLength - 1, -1, -1):
    target = readings[i]
    count = 0
    for j in range(i, -1, -1):
        diffsofar = target-readings[j]
        exact = target / 2
        if diffsofar  > exact:
            f = (exact - readings[j]) / (readings[j]-readings[j+1]) + count
            double[i] = f
            break
        else:
            count = count+1
print(double)  

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...