用 Pandas 模拟 Excel 个 AverageIF
Emulate Excel AverageIFs with Pandas
我正在尝试在某个日期范围内在 Pandas 中模拟 Excel 的 AVERAGEIFs 函数,但到目前为止还没有成功。我知道我需要使用 apply 和 groupby,但显然我的语法不正确,因为我收到此错误:
TypeError: can only concatenate list (not "Timedelta") to list
我目前正在使用测试数据,试图找出语法,数据如下:
对于每个 'Avg' 列,我试图 return 前 180 天的平均数量,按 'A' 和 'B' 分组。因此,我希望第 1 行中的 'Avg' 列为 1.5((1+2)/2,同时省略第 5 行,这是一个匹配项,但已超过 180 天)。
这是我目前的代码,它不起作用:
将 pandas 导入为 pd
#Importing the dataset
df = pd.read_excel('Test.xlsx', sheet_name='Sheet1')
df = pd.concat([df, pd.DataFrame(columns=['Avg Qty'])], axis=1)
df['Avg Qty'] = df.apply(df.groupby([(['Date'] <= (['Date']+pd.Timedelta(-1,
unit='d')) >= (['Date']+pd.Timedelta(-180, unit='d'))), 'A', 'B']))['Qty'].mean()
print(df.head)
如有任何帮助,我们将不胜感激。
IIUC,我想你想要这样的东西:
df['Avg Qty'] = (df.groupby([pd.Grouper(freq='180D', key='Date'),'A','B'])['Qty']
.transform('mean'))
输出:
Date A B Qty Cost Avg Qty
0 2017-12-11 Cancer Golf 1 100 1.5
1 2017-11-11 Cancer Golf 2 200 1.5
2 2017-11-11 Cardio Golf 2 300 2.0
3 2017-10-11 Cardio Baseball 3 600 3.0
4 2017-04-11 Cancer Golf 4 150 4.0
5 2016-01-01 Cancer Football 5 200 5.0
编辑:
df = df.set_index('Date')
df.groupby(['A','B']).apply(lambda x: x.sort_index().rolling('180D')['Qty'].mean()).reset_index()\
.merge(df.reset_index(), on=['Date','A','B'], suffixes=('_avg',''))
输出:
A B Date Qty_avg Qty Cost
0 Cancer Football 2016-01-01 5.0 5 200
1 Cancer Golf 2017-04-11 4.0 4 150
2 Cancer Golf 2017-11-11 2.0 2 200
3 Cancer Golf 2017-12-11 1.5 1 100
4 Cardio Baseball 2017-10-11 3.0 3 600
5 Cardio Golf 2017-11-11 2.0 2 300
我正在尝试在某个日期范围内在 Pandas 中模拟 Excel 的 AVERAGEIFs 函数,但到目前为止还没有成功。我知道我需要使用 apply 和 groupby,但显然我的语法不正确,因为我收到此错误:
TypeError: can only concatenate list (not "Timedelta") to list
我目前正在使用测试数据,试图找出语法,数据如下:
对于每个 'Avg' 列,我试图 return 前 180 天的平均数量,按 'A' 和 'B' 分组。因此,我希望第 1 行中的 'Avg' 列为 1.5((1+2)/2,同时省略第 5 行,这是一个匹配项,但已超过 180 天)。
这是我目前的代码,它不起作用: 将 pandas 导入为 pd
#Importing the dataset
df = pd.read_excel('Test.xlsx', sheet_name='Sheet1')
df = pd.concat([df, pd.DataFrame(columns=['Avg Qty'])], axis=1)
df['Avg Qty'] = df.apply(df.groupby([(['Date'] <= (['Date']+pd.Timedelta(-1,
unit='d')) >= (['Date']+pd.Timedelta(-180, unit='d'))), 'A', 'B']))['Qty'].mean()
print(df.head)
如有任何帮助,我们将不胜感激。
IIUC,我想你想要这样的东西:
df['Avg Qty'] = (df.groupby([pd.Grouper(freq='180D', key='Date'),'A','B'])['Qty']
.transform('mean'))
输出:
Date A B Qty Cost Avg Qty
0 2017-12-11 Cancer Golf 1 100 1.5
1 2017-11-11 Cancer Golf 2 200 1.5
2 2017-11-11 Cardio Golf 2 300 2.0
3 2017-10-11 Cardio Baseball 3 600 3.0
4 2017-04-11 Cancer Golf 4 150 4.0
5 2016-01-01 Cancer Football 5 200 5.0
编辑:
df = df.set_index('Date')
df.groupby(['A','B']).apply(lambda x: x.sort_index().rolling('180D')['Qty'].mean()).reset_index()\
.merge(df.reset_index(), on=['Date','A','B'], suffixes=('_avg',''))
输出:
A B Date Qty_avg Qty Cost
0 Cancer Football 2016-01-01 5.0 5 200
1 Cancer Golf 2017-04-11 4.0 4 150
2 Cancer Golf 2017-11-11 2.0 2 200
3 Cancer Golf 2017-12-11 1.5 1 100
4 Cardio Baseball 2017-10-11 3.0 3 600
5 Cardio Golf 2017-11-11 2.0 2 300