Python 分组并取当月前三个日期的平均值?

Python 分组并取当月前三个日期的平均值?,python,pandas,Python,Pandas,我有一个每周的数据帧,我需要与每月的数据帧合并。数据帧如下所示: Date Value 2020-01-01 2 2020-01-08 2 2020-01-16 2 2020-01-24 1 2020-02-01 1 2020-02-08 1 2020-02-16 1 2020-02-24 1 我想按日期分组以与其他数据帧合并,但只取该月前三个日期的平均值(不假设每个月的天数相

我有一个每周的数据帧,我需要与每月的数据帧合并。数据帧如下所示:

Date            Value
2020-01-01       2
2020-01-08       2
2020-01-16       2
2020-01-24       1
2020-02-01       1
2020-02-08       1
2020-02-16       1
2020-02-24       1
我想按日期分组以与其他数据帧合并,但只取该月前三个日期的平均值(不假设每个月的天数相同)。我怎么能这样做


谢谢你

创建一个仅年\月的列,按它分组并应用func获得前3个的平均值:

df['YM'] = df['Date'].dt.strftime('%Y-%m')
pd.DataFrame(df.groupby('YM').apply(lambda x: x['Value'].iloc[:3].mean()))

创建一个仅年\月列,按其分组并应用func以获取前3个的平均值:

df['YM'] = df['Date'].dt.strftime('%Y-%m')
pd.DataFrame(df.groupby('YM').apply(lambda x: x['Value'].iloc[:3].mean()))

有一个更优雅的解决方案,但这是如何将问题分解成小块,让您解决这个问题。大多数答案可以在一行代码中打断这三个步骤

# first group by month
df['date_trunc'] = pd.to_datetime(df['Date']).dt.to_period('M')

# make a row number
df['row_number'] = df.groupby('date_trunc').cumcount()+1

         Date  Value date_trunc  row_number
0  2020-01-01      2    2020-01           1
1  2020-01-08      2    2020-01           2
2  2020-01-16      2    2020-01           3
3  2020-01-24      1    2020-01           4
4  2020-02-01      1    2020-02           1
5  2020-02-08      1    2020-02           2
6  2020-02-16      1    2020-02           3
7  2020-02-24      1    2020-02           4

# then filter to only values 3 or below and groupby the date_trunc and take the mean!
df.loc[df['row_number']<=3].groupby('date_trunc').mean()['Value']

date_trunc
2020-01    2
2020-02    1
#每月第一组
df['date\u trunc']=pd.to\u datetime(df['date']).dt.to\u period('M')
#排成一行
df['row\u number']=df.groupby('date\u trunc').cumcount()+1
日期值日期列号
0  2020-01-01      2    2020-01           1
1  2020-01-08      2    2020-01           2
2  2020-01-16      2    2020-01           3
3  2020-01-24      1    2020-01           4
4  2020-02-01      1    2020-02           1
5  2020-02-08      1    2020-02           2
6  2020-02-16      1    2020-02           3
7  2020-02-24      1    2020-02           4
#然后只过滤到值3或以下,并按日期分组,取平均值!

df.loc[df['row_number']有一个更优雅的解决方案,但这是如何将问题分解成小块,让您解决这个问题。大多数答案可以在一行代码中分解这三个步骤

# first group by month
df['date_trunc'] = pd.to_datetime(df['Date']).dt.to_period('M')

# make a row number
df['row_number'] = df.groupby('date_trunc').cumcount()+1

         Date  Value date_trunc  row_number
0  2020-01-01      2    2020-01           1
1  2020-01-08      2    2020-01           2
2  2020-01-16      2    2020-01           3
3  2020-01-24      1    2020-01           4
4  2020-02-01      1    2020-02           1
5  2020-02-08      1    2020-02           2
6  2020-02-16      1    2020-02           3
7  2020-02-24      1    2020-02           4

# then filter to only values 3 or below and groupby the date_trunc and take the mean!
df.loc[df['row_number']<=3].groupby('date_trunc').mean()['Value']

date_trunc
2020-01    2
2020-02    1
#每月第一组
df['date\u trunc']=pd.to\u datetime(df['date']).dt.to\u period('M')
#排成一行
df['row\u number']=df.groupby('date\u trunc').cumcount()+1
日期值日期列号
0  2020-01-01      2    2020-01           1
1  2020-01-08      2    2020-01           2
2  2020-01-16      2    2020-01           3
3  2020-01-24      1    2020-01           4
4  2020-02-01      1    2020-02           1
5  2020-02-08      1    2020-02           2
6  2020-02-16      1    2020-02           3
7  2020-02-24      1    2020-02           4
#然后只过滤到值3或以下,并按日期分组,取平均值!

df.loc[df['row_number']也可以这样做,类似于以西结的:

df['grouper'] = df['Date'].str.extract('(\d{4}-\d{2})')
df.groupby('grouper')['Value'].apply(lambda x: sum(x[:3])/3)
输出:

grouper
2020-01    2.0
2020-02    1.0
Name: Value, dtype: float64

也可以这样做,类似于以西结的:

df['grouper'] = df['Date'].str.extract('(\d{4}-\d{2})')
df.groupby('grouper')['Value'].apply(lambda x: sum(x[:3])/3)
输出:

grouper
2020-01    2.0
2020-02    1.0
Name: Value, dtype: float64

不确定为什么Andrej Kesely删除了他们的答案,但它认为这是最干净的:

df["month_key"] = df["Date"].dt.to_period("M")
df.groupby("month_key").head(3).groupby("month_key").mean()
导致

           Value
month_key       
2020-01        2
2020-02        1

不确定为什么Andrej Kesely删除了他们的答案,但它认为这是最干净的:

df["month_key"] = df["Date"].dt.to_period("M")
df.groupby("month_key").head(3).groupby("month_key").mean()
导致

           Value
month_key       
2020-01        2
2020-02        1

您只需重新采样并取前3个值的平均值:

df.set_index('Date').resample('MS').agg(lambda x: x.iloc[:3].mean())
它给出:

            Value
Date             
2020-01-01      2
2020-02-01      1
如果要返回日期列,可以
reset\u index

df.set_index('Date').resample('MS').agg(lambda x: x.iloc[:3].mean()).reset_index()
拥有:

        Date  Value
0 2020-01-01      2
1 2020-02-01      1

您只需重新采样并取前3个值的平均值:

df.set_index('Date').resample('MS').agg(lambda x: x.iloc[:3].mean())
它给出:

            Value
Date             
2020-01-01      2
2020-02-01      1
如果要返回日期列,可以
reset\u index

df.set_index('Date').resample('MS').agg(lambda x: x.iloc[:3].mean()).reset_index()
拥有:

        Date  Value
0 2020-01-01      2
1 2020-02-01      1

你的意思是每个唯一月份的前3个条目取平均值吗?因为间隔不一定是1day@DerekEden是的,每个独特月份的前3个条目,因此对于2020年1月,您将取1月1日、8日和16日的平均值,忽略最后一个(24日)你的意思是每个唯一月份的前3个条目取平均值吗?因为间隔不一定是1day@DerekEden是的,每个独特月份的前3个条目,因此对于2020年1月,您将取1月1日、8日和16日的平均值,忽略最后一个(24日)这假设日期是字符串,在YYYY-MM-DD格式中这假设日期是字符串,在YYYY-MM-DD格式中为什么
cumcount()+1
?如果你只使用
cumcount()
,那么你可以使用
df['row\u number']=3
@Dan,我想你的意思是
为什么
cumcount()+1
?如果你只使用
cumcount()
那么你可以使用
df['row\u number']=3
@Dan,我想你的意思是
作为注释,这假设日期是DateTimes,如果不是,我建议将其转换为:
df[“Date”]=pd.to\u datetime(df[“Date”])
我同意……作为注释,这假设日期是DateTimes,如果不是,我建议将其转换为:
df[“日期”]=pd.to_datetime(df[“Date”])
我同意。