Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在滚动窗口聚合的同时保持索引列的唯一性?_Python_Pandas - Fatal编程技术网

Python 如何在滚动窗口聚合的同时保持索引列的唯一性?

Python 如何在滚动窗口聚合的同时保持索引列的唯一性?,python,pandas,Python,Pandas,我希望滚动窗口聚合一个数据帧,但我的结果保留一个具有唯一索引的列是至关重要的,因为稍后我希望将聚合重新加入到原始数据帧中 很像 df = pd.DataFrame( {"id": range(6), "t": [pd.Timestamp("2019-01-01")+dt.timedelta(seconds=sec) for sec in [2, 2, 1, 1, 1, 1]], "gr": list("ababab"), "val": range(6)}) agg

我希望滚动窗口聚合一个数据帧,但我的结果保留一个具有唯一索引的列是至关重要的,因为稍后我希望将聚合重新加入到原始数据帧中

很像

df = pd.DataFrame(
   {"id": range(6),
    "t": [pd.Timestamp("2019-01-01")+dt.timedelta(seconds=sec) for sec in [2, 2, 1, 1, 1, 1]],
    "gr": list("ababab"),
    "val": range(6)})

agg = df.groupby("gr").rolling("2s", on="t")["val"].sum()  # <- id not present anymore
预期金额应为

   id                   t gr  sum_val
2   3 2019-01-01 00:00:01  a    2
4   1 2019-01-01 00:00:01  a    6
0   5 2019-01-01 00:00:02  a    6
3   2 2019-01-01 00:00:01  b    3
5   0 2019-01-01 00:00:01  b    8
1   4 2019-01-01 00:00:02  b    9
然而,一个建议解决方案的输出是

agg = df.sort_values("t").groupby(['gr']).rolling("2s", on="t")['val'].sum().reset_index(name='sum_val')
agg['id'] = df.sort_values(['gr'])['id'].values
agg.sort_values(["gr", "t"])
输出:

  gr                   t  sum_val  id
0  a 2019-01-01 00:00:01      2.0   5
1  a 2019-01-01 00:00:01      6.0   3
2  a 2019-01-01 00:00:02      6.0   1
3  b 2019-01-01 00:00:01      3.0   4
4  b 2019-01-01 00:00:01      8.0   2
5  b 2019-01-01 00:00:02      9.0   0
    gr  t   sum_val id
0   a   1   NaN 0
1   a   1   2.0 2
2   a   2   6.0 4
3   b   1   NaN 1
4   b   1   4.0 3
5   b   2   8.0 5
    gr  t   sum_val id
0   a   1   NaN      0
1   a   2   2.0      2
2   a   3   6.0      4
3   b   1   NaN      1
4   b   2   4.0      3
5   b   3   8.0      5
   id  t gr  val  roll
0   0  1  a    0   NaN
1   1  1  b    1   NaN
2   2  1  a    2   2.0
3   3  1  b    3   4.0
4   4  2  a    4   6.0
5   5  2  b    5   8.0
gr='a'
id=5
应该是6吗

更新:为了演示问题,我将时间重复了很多次。
更新:将
t
设置为时间列,因为之前它没有执行它应该执行的操作。

由于
t
在组内是非唯一的,但
id
是唯一的,并且您正在
gr
上分组,因此您可以执行以下操作:

agg = df.groupby(['gr']).rolling(2, on="t")['val'].sum().reset_index(name='sum_val')
agg['id'] = df.sort_values(['gr'])['id'].values
输出:

  gr                   t  sum_val  id
0  a 2019-01-01 00:00:01      2.0   5
1  a 2019-01-01 00:00:01      6.0   3
2  a 2019-01-01 00:00:02      6.0   1
3  b 2019-01-01 00:00:01      3.0   4
4  b 2019-01-01 00:00:01      8.0   2
5  b 2019-01-01 00:00:02      9.0   0
    gr  t   sum_val id
0   a   1   NaN 0
1   a   1   2.0 2
2   a   2   6.0 4
3   b   1   NaN 1
4   b   1   4.0 3
5   b   2   8.0 5
    gr  t   sum_val id
0   a   1   NaN      0
1   a   2   2.0      2
2   a   3   6.0      4
3   b   1   NaN      1
4   b   2   4.0      3
5   b   3   8.0      5
   id  t gr  val  roll
0   0  1  a    0   NaN
1   1  1  b    1   NaN
2   2  1  a    2   2.0
3   3  1  b    3   4.0
4   4  2  a    4   6.0
5   5  2  b    5   8.0
如果
t
是唯一的,则可以执行以下操作:

agg = df.groupby(['gr']).rolling(2, on="t")['val'].sum().reset_index(name='sum_val')
agg['id'] = df.sort_values(['gr'])['id'].values
您可以合并回原始df

df.groupby(['gr']).rolling(2, on="t")['val'].sum().reset_index(name='sum_val').merge(df[['id', 't', 'gr']])
输出:

  gr                   t  sum_val  id
0  a 2019-01-01 00:00:01      2.0   5
1  a 2019-01-01 00:00:01      6.0   3
2  a 2019-01-01 00:00:02      6.0   1
3  b 2019-01-01 00:00:01      3.0   4
4  b 2019-01-01 00:00:01      8.0   2
5  b 2019-01-01 00:00:02      9.0   0
    gr  t   sum_val id
0   a   1   NaN 0
1   a   1   2.0 2
2   a   2   6.0 4
3   b   1   NaN 1
4   b   1   4.0 3
5   b   2   8.0 5
    gr  t   sum_val id
0   a   1   NaN      0
1   a   2   2.0      2
2   a   3   6.0      4
3   b   1   NaN      1
4   b   2   4.0      3
5   b   3   8.0      5
   id  t gr  val  roll
0   0  1  a    0   NaN
1   1  1  b    1   NaN
2   2  1  a    2   2.0
3   3  1  b    3   4.0
4   4  2  a    4   6.0
5   5  2  b    5   8.0
你是说:

df['roll'] = (df.groupby("gr", as_index=False, group_keys=False)
                .apply(lambda x: x.rolling(2, on='t')['val'].sum())
             )
输出:

  gr                   t  sum_val  id
0  a 2019-01-01 00:00:01      2.0   5
1  a 2019-01-01 00:00:01      6.0   3
2  a 2019-01-01 00:00:02      6.0   1
3  b 2019-01-01 00:00:01      3.0   4
4  b 2019-01-01 00:00:01      8.0   2
5  b 2019-01-01 00:00:02      9.0   0
    gr  t   sum_val id
0   a   1   NaN 0
1   a   1   2.0 2
2   a   2   6.0 4
3   b   1   NaN 1
4   b   1   4.0 3
5   b   2   8.0 5
    gr  t   sum_val id
0   a   1   NaN      0
1   a   2   2.0      2
2   a   3   6.0      4
3   b   1   NaN      1
4   b   2   4.0      3
5   b   3   8.0      5
   id  t gr  val  roll
0   0  1  a    0   NaN
1   1  1  b    1   NaN
2   2  1  a    2   2.0
3   3  1  b    3   4.0
4   4  2  a    4   6.0
5   5  2  b    5   8.0

如何执行
agg.reset_index()
?由于将
id
与其他id的滚动总和相关联看起来没有多大意义,因此您到底希望得到什么。我调整了示例,使时间在组内不唯一。这就是问题的根源。@QuangHoang我需要以某种方式将聚合回滚到原始数据帧中。这应该是一个有意义的行动?身份证只是为了找到正确的位置。哦,对了。但我意识到我的问题来自于时间的非唯一性,即使是在群体中。我调整了我的榜样。那我就不能再毫不含糊地加入了?!更新了我的答案@GerenukBut
b
以前有id 1,3,5,现在在第一个示例中有了3,4,5?@Gerenuk,忘记将
id
作为数组。对于这个系列,它使用原始索引,这是错误的。修正了。(
.values
)我意识到熊猫没有做我想做的事,也没有警告我。上的
无效。如果我将
t
更改为time,而将窗口更改为
“2s”
则熊猫会在没有警告的情况下计算错误。但一旦您意识到这一点,并在
t
上预排序,您的排序技巧就可以再次发挥作用。