两个时间序列的python聚合

时间:2019-02-28 21:36:01

标签: python pandas time-series aggregation

我有两个熊猫时间序列数据帧,我想基于另一个时间间隔的时间值来汇总一个时间序列的值。让我以身作则。 第一次时间序列如下:

        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中使用循环(最好是使用循环)的方法吗?

3 个答案:

答案 0 :(得分:5)

您可以根据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

答案 1 :(得分:4)

脾气暴躁的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的类型为floatv也会强制转换为int

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

答案 2 :(得分:3)

只要有时间添加我的解决方案,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