如何将累积数据转换为每日数据?

How to convert cumulative data to daily one?

我有一份 link 的累计传输数据列表以及数据传输开始和结束的时间段。也就是说,times的元素是天的周期; data 的元素是 所有 由此 link 传输到当前传输结束的数据的总和:

data = [0.85, 1.6, 1.85, 2.89, 3.56, 4.05, 5.56, 7.89]
times = [[0.5, 1.3], [1.8, 2.1], [2.9, 2.99], [3.5, 3.59], [3.6, 4.1], [4.2, 4.35], [4.65, 4.76], [4.85, 5.5]]

有什么python或numpy方法可以将累积数据转换为传输数据的每日([0, 1], [1, 2], [2, 3], [3, 4,], [4, 5], [5, 6])统计信息吗?

P.S 每日数据是指传输了多少数据,特别是在 01 期间(12 等等)。

例如,我想查找在 0 天和 1 天之间传输的数据。在 [0.5, 1.3] 0.85 GB 期间传输了数据。所以我必须找到在 [0, 1].
之间转移的 0.85 GB 的一部分 0.85 GB * (1-0.5) days / (1.3-0.5) days = 0.53 GB 等等。

IIUC 你可以这样做 -

lims = np.arange(data.size)+1
col0 = lims - times[:,0]
col1 = times[:,1] - lims
lens = times[:,1] - times[:,0]

out = data*col0/lens
shares = data*(col1/lens)
out[1:] += shares.cumsum()[:-1]

样本运行-

In [144]: data
Out[144]: array([ 0.85,  1.6 ,  1.85,  2.89,  3.56,  4.05,  5.56,  7.89])

In [145]: times
Out[145]: 
array([[ 0.5 ,  1.3 ],
       [ 1.8 ,  2.1 ],
       [ 2.9 ,  2.99],
       [ 3.5 ,  3.59],
       [ 3.6 ,  4.1 ],
       [ 4.2 ,  4.35],
       [ 4.65,  4.76],
       [ 4.85,  5.5 ]])

In [146]: out
Out[146]: 
array([   0.53125   ,    1.38541667,    2.90763889,   16.70208333,
         -2.55102778,   29.67297222,   55.3047904 , -138.46269211])

您可以使用 np.split 将数据分块到每日数组中。首先,您需要定义每一天边缘的索引;为此,您可以使用 np.histogram 来定义代表您生活边缘的容器。然后 cumsum 得到每一天的边缘指数。

hist, bins = np.histogram(times, bins=range(5)) # 5 is number of days
chunked = np.split(data, hist.cumsum())

Chunked 现在应该是一个数组列表,其中每个数组都包含每天的值。你可以应用任何你想要的减少功能。

print(chunked)   
# [array([0.85]), array([1.6, 1.85]), ...]

map(np.sum, chunked)

注意 times/values 数组必须排序才能拆分。

...

更具可读性但速度更慢,您可以 select 每天的数据。

days = np.floor(times)
chunked = [data[days == day] for day in range(5)]

@Divakar 已经发布了正确的 numpy 解决方案,这里有一个简单的 python 解决方案:

import math
data = [0.85, 1.6, 1.85, 2.89, 3.56, 4.05, 5.56, 7.89]
times = [0.5, 1.3, 1.8, 2.9, 3.5, 3.6, 4.2, 4.65]
daily = [0] * 7

for i, t in enumerate(times):
    daily[int(math.floor(t))] += data[i]

print daily