【问题标题】:python aggregation of two time-series两个时间序列的python聚合
【发布时间】:2019-07-22 21:32:28
【问题描述】:

我有两个 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中不使用循环(最好)的方法?

【问题讨论】:

  • @Vaishali 我认为问题不同......

标签: python pandas time-series aggregation


【解决方案1】:

您可以根据 df2 日期中的 bin 对 df1 中的数据进行 bin,

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

【讨论】:

  • 不平凡的问题和很好的答案。快来偷看!赏识在哪里?
  • 这个就够了?
  • 还有一个 ?
  • 优秀的答案! :)
【解决方案2】:

麻木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 转换为float,即使vint 类型。

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

【讨论】:

  • 绝妙的解决方案!虽然我还没有完全理解。 :D 谢谢。
  • 解释工作
  • 请让我至少自己做;)
  • 这是一个快速而肮脏的解释。现在下班开车。祝你好运。
  • 现在看到了,没用过searchsorted。有很多东西要学:)
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-24
    • 2015-05-28
    • 2016-02-03
    • 2011-04-28
    • 2015-10-11
    • 2023-03-07
    • 1970-01-01
    • 2018-07-03
    相关资源
    最近更新 更多