在 Pandas 中获取特定日期范围的平均值

4

我需要按网站分组数据,并获取特定日期范围内浏览量的平均值。我的数据看起来像这样:

date        website         amount_views
1/1/2021        a               23
1/2/2021        a               17
1/3/2021        a               10
1/4/2021        a               25
1/5/2021        a               2
1/1/2021        b               12
1/2/2021        b               7
1/3/2021        b               5
1/4/2021        b               17
1/5/2021        b               2

所以我需要查看 a 和 b 网站在日期范围为 2021 年 1 月 1 日至 2021 年 3 月 1 日(前)和 2021 年 3 月 1 日至 2021 年 5 月 1 日(后)的平均数据。

期望的输出结果为:

date        website         avg_amount_views
pre            a                 31.5
post           a                 35.6
pre            b                 15.5
post           b                 22.6
4个回答

6
你可以使用 np.where 和 date.between 来分配前后状态,按相同的网站和组进行分组,并找到平均值。
一行代码实现(虽然不太易读):
  df['date']=pd.to_datetime(df['date'])
  df.groupby([np.where(df['date'].between('1/1/2021','1/3/2021'),'pre'\
  ,'post'),'website'])['amount_views'].mean().to_frame('mean')

逐步操作(更易读):

df['date']=pd.to_datetime(df['date'])
df['status']=np.where(df['date'].between('1/1/2021','1/3/2021'),'pre','post')
df.groupby(['status','website'])['amount_views'].mean().to_frame('mean')

                     mean
status website           
post   a        13.500000
       b         9.500000
pre    a        16.666667
       b         8.000000

4
  • 使用pandas.Grouper并将 freq 参数设置为 'W',表示每周。
import pandas as pd

# test dataframe
data = {'date': ['1/1/2021', '1/2/2021', '1/3/2021', '1/4/2021', '1/5/2021', '1/1/2021', '1/2/2021', '1/3/2021', '1/4/2021', '1/5/2021'], 'website': ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b'], 'amount_views': [23, 17, 10, 25, 2, 12, 7, 5, 17, 2]}

df = pd.DataFrame(data)

# set the date column to a datetime format - required
df.date = pd.to_datetime(df.date)

# groupby with pd.Grouper
mean_visits = df.groupby([pd.Grouper(key='date', freq='W'), 'website'])['amount_views'].mean().reset_index(name='mean_visits')

# display(mean_visits)
        date website  mean_visits
0 2021-01-03       a    16.666667
1 2021-01-03       b     8.000000
2 2021-01-10       a    13.500000
3 2021-01-10       b     9.500000

4

用法:

dates = pd.to_datetime(df['date'])
new_df = (df.groupby(['website', np.select((dates.between('1/1/2021', '1/3/2021'), 
                                           dates.between('1/3/2021', '1/5/2021')), 
                                           ('pre', 'pos'))])
            .amount_views
            .mean()
            .rename_axis(('website', 'date'))
            .reset_index(name='avg_amount_views'))
print(new_df)

  website date  avg_amount_views
0       a  pos         13.500000
1       a  pre         16.666667
2       b  pos          9.500000
3       b  pre          8.000000

4
您可以使用pd.cut来定义“前”和“后”:
grp = pd.cut(df['date'], bins=[pd.Timestamp(2021, 1, 1), 
                               pd.Timestamp(2021, 1, 3), 
                               pd.Timestamp(2021, 1, 6)], labels=['pre', 'post'],
      right=False)

df.groupby([grp, 'website'])['amount_views'].agg(['mean','count']).reset_index()

输出:

   date website       mean  count
0   pre       a  20.000000      2
1   pre       b   9.500000      2
2  post       a  12.333333      3
3  post       b   8.000000      3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接