【问题标题】:Is there a way to do rolling count with groupby 2 columns in Pandas?有没有办法在 Pandas 中使用 groupby 2 列进行滚动计数?
【发布时间】:2019-09-08 01:41:30
【问题描述】:

我希望能够计算某个位置在 7 天内出现的次数。我尝试了几种组合 groupby、rolling 和 Grouper 的方法,但仍然没有得到我想要的结果。如何按 2 列分组以获得我想要的结果?

这是一个示例表:

locations = ['A', 'B', 'A', 'B', 'C','C']
df = pd.DataFrame({'date': times,'location': locations})
     date     location
0   2014-08-25  A
1   2014-08-26  B
2   2014-08-26  A
3   2014-09-11  B
4   2014-09-12  C
5   2014-09-15  C

我试过了:

df.set_index('date', inplace=True)
df['roll']=df.groupby('location')['location'].rolling(7).count().reset_index(0,drop=True)

但是给我这个:

         location   roll
date        
2014-08-25  A   1.0
2014-08-26  B   2.0
2014-08-26  A   1.0
2014-09-11  B   2.0
2014-09-12  C   1.0
2014-09-15  C   2.0

我想要的输出应该是这样的:

times = pd.to_datetime(pd.Series(['2014-08-25','2014-08-26','2014-08-26','2014-09-11','2014-09-12', '2014-09-15']))
locations = ['A', 'B', 'A', 'B', 'C','C']
count = [1, 1, 2, 1, 1, 2]
df1 = pd.DataFrame({'date': times,'location': locations, 'rolling_count':count})

    date    location    rolling_count
0   2014-08-25  A   1
1   2014-08-26  B   1
2   2014-08-26  A   2
3   2014-09-11  B   1
4   2014-09-12  C   1
5   2014-09-15  C   2

【问题讨论】:

标签: pandas


【解决方案1】:

可以通过Grouper(例如df.groupby(Grouper(key='date', freq='7d')))来计算某个位置在 7 天内出现的次数。

但是在滚动窗口中进行观察计数可以提供更多信息。这不是“每周”,它本身总是很难定义,在处理日历年和月时应始终避免。

对于所有在一列中的唯一观察值的滚动计数。所以需要一些技巧:

  • 旋转 DataFrame 并将位置放入列中。这大大 有助于计算独特的观察结果。
  • 标准化日期时间索引。这样可以滑动 7 天的窗口 沿着索引。

结果是随着窗口在观察结果上滑动,计数增加然后减少。

import pandas as pd
print(pd.__version__)

times = ['2014-08-25', '2014-08-26', '2014-08-26', '2014-09-11', '2014-09-12', '2014-09-15', '2014-09-16']
locations = ['A', 'B', 'A', 'B', 'C','C', 'C']
df = pd.DataFrame({'date': times,'location': locations})

# multiple locations can be observed in a single day
df = df.pivot(index='date', columns='location', values='location')

# set up a datetime index
df.index = pd.to_datetime(df.index)

# normalize the days so an entire 7 day window can be rolled
df = df.resample('1d').last()

# count the number of observations in the window per location
# TODO: functional way to do this?
for col in df.columns:
    df['{}_7d_observations'.format(col)] = df[col].rolling(7).count()

print(df)

产生类似的东西

location      A    B    C  A_7d_observations  B_7d_observations  C_7d_observations
date                                                                              
2014-08-25    A  NaN  NaN                1.0                0.0                0.0
2014-08-26    A    B  NaN                2.0                1.0                0.0
...snip...
2014-08-31  NaN  NaN  NaN                2.0                1.0                0.0
2014-09-01  NaN  NaN  NaN                1.0                1.0                0.0
...snip...
2014-09-10  NaN  NaN  NaN                0.0                0.0                0.0
2014-09-11  NaN    B  NaN                0.0                1.0                0.0
2014-09-12  NaN  NaN    C                0.0                1.0                1.0
2014-09-13  NaN  NaN  NaN                0.0                1.0                1.0
2014-09-14  NaN  NaN  NaN                0.0                1.0                1.0
2014-09-15  NaN  NaN    C                0.0                1.0                2.0
2014-09-16  NaN  NaN    C                0.0                1.0                3.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 2021-09-21
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    相关资源
    最近更新 更多