Python 如何计算;倍增时间“;使用Pandas或Numpy计算离散时间序列?

Python 如何计算;倍增时间“;使用Pandas或Numpy计算离散时间序列?,python,pandas,numpy,Python,Pandas,Numpy,这是一个数据集。每一行都是一个时间片。第一栏是阅读。第二个问题是多少个时间片之前的读数是它的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

这是一个数据集。每一行都是一个时间片。第一栏是阅读。第二个问题是多少个时间片之前的读数是它的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
因此,假设我有一个数据帧,如下所示:

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

如何计算df.double?我可以想象从最后开始,然后向后工作,每次扫描我开始值的50%。但是有更好的办法。我认为这与Log2有关,但不确定如何做

你在研究新冠病毒-19感染加倍时间吗

请仔细检查结果。

我忘了你正在使用熊猫,所以你可能首先需要这个:

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轴需要移动。或者说到底这是正确的。 明天我会用一个全新的头脑来思考这个问题

下一幅图显示了这两种算法的计算指数数据,其中两个位置设置为非递增值


是的,我正在处理这些数据。这是一个老派的解决方案。我找到了你的解决办法,但还是不太明白。但我的不太优雅,但我认为这是正确的。。。这张图看起来很像你的

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)  

可能最终会看起来像这样

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)

你需要确切的时间片吗?也许拟合某条直线x=f(t)会更容易,然后根据它进行计算。使用当前的解决方案,您可能会遇到两个或多个时间片保持50%值的问题。我认为我不能假设太多的模式。因此,直线拟合程度可能较高。如果两个或更多的时间片保持50%的值,那么我会选择最早的一个。所以,如果数据是50,50,50,100,那么倍增时间是,,u4。看,我知道如何用手来做,但不确定算法…如果你愿意在熊猫之外做,我想这会很容易。在数组中循环,然后从开始循环到当前索引,寻找50%的值。不幸的是,我想不出一个方法来做这件事。几天前我也在尝试类似的事情,但找不到一个好的解决方案,我专注于插值。它工作正常,但问题是如果两个连续的值相同。这必须用手来处理。对于使用log2的解决方案,可能需要一个拟合,如上所述。我想我得到了一个解决方案,只需一秒钟。嗯,这些图看起来非常不同,我会将它们与您的方法一起绘制。让我看看。你也用直线方程的线性插值,对吗?不,我错了,结果很相似。在中间有一个偏差,你的方法似乎处理不同的开始和结束。请参阅我答案中的更新图片。偏差可能是我添加到数据中的没有增加的点。此外,我选择将第一个点保留为零,因为我们不知道它们的倍增时间……谢谢大家。最后的结果是:我喜欢它。但我更喜欢倍增时间:)