[英]python aggregation of two time-series
我有兩個pandas時間序列數據幀,我想根據另一個時間序列的時間間隔將值匯總到一個時間序列。 讓我舉例說明。 第一個時間序列如下:
date value
0 2016-03-21 10
1 2016-03-25 10
2 2016-04-10 10
3 2016-05-05 10
第二個是從上述系列中提取的具有10個日歷日間隔的日期范圍。 我編寫了代碼以從上面的數據中提取。
date
0 2016-03-21
1 2016-03-31
2 2016-04-10
3 2016-04-20
4 2016-04-30
我想寫一些代碼來獲得這個結果數據幀:
date value
0 2016-03-21 20
1 2016-03-31 0
2 2016-04-10 10
3 2016-04-20 0
4 2016-04-30 10
請不要在python中使用循環(最好),建議一種方法來做到這一點?
你可以根據df2日期的bin,在df1中對數據進行分區,
bins = pd.date_range(df2.date.min(), df2.date.max() + pd.DateOffset(10), freq = '10D')
labels = df2.date
df1.groupby(pd.cut(df1.date, bins = bins, right = False, labels = labels)).value.sum().reset_index()
date value
0 2016-03-21 20
1 2016-03-31 0
2 2016-04-10 10
3 2016-04-20 0
4 2016-04-30 10
searchsorted
這是我想到的第一件事,但要解決這個問題並非易事。 @Vaishali的答案在精神上與此非常相似且更簡單。 但我就像一條骨頭的狗,我不能放手,直到我弄明白。
解釋一下。 searchsorted
將通過一個數組,在這種情況下是等間隔的日期,並找到它們將被放置在另一個數組中的位置以保持排序。 這聽起來很復雜但如果我們想象,我們可以看到發生了什么。 我會用信件來證明。 我會選擇與日期對應的字母。
x = np.array([*'abdg'])
y = np.array([*'acdef'])
請注意,在每個字母x
我發現那里的逆止是y
# i -> 0 0 2 4
# x -> a b d g
# y -> a c d e f
這適用於我在下面做的事情。
df = pd.DataFrame(dict(
date=pd.to_datetime(['2016-03-21', '2016-03-25', '2016-04-10', '2016-05-05']),
value=[10, 10, 10, 10]
))
dates = pd.date_range(df.date.min(), df.date.max(), freq='10D')
d = df.date.values
v = df.value.values
i = dates.searchsorted(d, side='right') - 1
a = np.zeros(len(dates), dtype=v.dtype)
np.add.at(a, i, v)
pd.DataFrame(dict(
date=dates, value=a
))
date value
0 2016-03-21 20
1 2016-03-31 0
2 2016-04-10 10
3 2016-04-20 0
4 2016-04-30 10
你會發現我用np.add.at
序總結v
在恰當的地點。 我也可以用np.bincount
做到這np.bincount
。 我更喜歡上面的方法,因為即使v
是int
類型, np.bincount
轉換為float
。
d = df.date.values
v = df.value.values
i = dates.searchsorted(d, side='right') - 1
pd.DataFrame(dict(
date=dates, value=np.bincount(i, v).astype(v.dtype)
))
date value
0 2016-03-21 20
1 2016-03-31 0
2 2016-04-10 10
3 2016-04-20 0
4 2016-04-30 10
只是有時間添加我的解決方案, numpy
廣播
s1=df1.date.values
s2=df2.date.values
a=(np.abs(s1-s2[:,None])/np.timedelta64(60*60*24, 's')<10).dot(df1.value.values)
a
Out[183]: array([20, 10, 10, 0, 10], dtype=int64)
#df2['value']=a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.