我必须执行多个transform-groupby-aggregate操作,并且当前正在一个接一个地执行这些操作,但这非常慢:
from pandas.tseries.offsets import MonthEnd
import pandas as pd
fsc = ['E', 'P']
mtx = pd.DataFrame({'EQ': {'2': 'P', '9970': 'P', '9971': 'P'},
'HOURS': {'2': 7.2000000000000002, '9970': 18.0, '9971': 10.0},
'LOC': {'2': 'A', '9970': 'B', '9971': 'B'},
'ORG': {'2': 23, '9970': 52, '9971': 52},
'START': {'2': pd.Timestamp('2014-07-31 17:21:59'),
'9970': pd.Timestamp('2011-12-15 17:59:59'),
'9971': pd.Timestamp('2011-08-07 04:59:59')}})
monthly = pd.DataFrame(pd.date_range(start='1970-01-01', end="2017-04-01 23:59:59", freq="MS"))[0].transform(lambda m : (( mtx.loc[(mtx["EQ"].isin(fsc)) & (mtx["START"] >= pd.to_datetime(m)) & (mtx["START"] <= pd.to_datetime(m) + MonthEnd(1))]).groupby(["ORG","LOC"])["HOURS"].mean()))
monthly = monthly.stack().stack().reset_index()
monthly_tmp = pd.DataFrame(pd.date_range(start='1970-01-01', end="2017-04-01 23:59:59", freq="MS"))[0].transform(lambda m : (( mtx.loc[(mtx["EQ"].isin(fsc)) & (mtx["START"] >= pd.to_datetime(m)) & (mtx["START"] <= pd.to_datetime(m) + MonthEnd(1))]).groupby(["ORG","LOC"])["HOURS"].sum()))
monthly = pd.merge(monthly,monthly_tmp.stack().stack().reset_index(),on=["level_0","LOC","ORG"],how="left")
给予:
pd.DataFrame({'0_x': {0: 10.0, 1: 18.0},
'0_y': {0: 10.0, 1: 18.0},
'LOC': {0: 'B', 1: 'B'},
'ORG': {0: 52, 1: 52},
'level_0': {0: 499, 1: 503}}
如何一次完成所有这些操作? 我尝试过:
f = {'HOURS': 'mean','HOURS': 'sum'}
pd.DataFrame(pd.date_range(start='1970-01-01', end="2017-04-01 23:59:59", freq="MS"))[0].transform(lambda m : (( mtx.loc[(mtx["EQ"].isin(fsc)) & (mtx["START"] >= pd.to_datetime(m)) & (mtx["START"] <= pd.to_datetime(m) + MonthEnd(1))]).groupby(["ORG","LOC"]).agg(f)))
但是它以另一种奇怪的方式返回DataFrame。
答案 0 :(得分:1)
您可以将.agg()
与转置一起使用。它不会给您确切的输出,但是您可以在熊猫中进行操作:
.groupby(["ORG","LOC"])['HOURS'].agg(['mean', 'sum']).T.unstack())).stack().stack().stack().reset_index()
所以仅使用您的示例
new_df = pd.DataFrame(pd.date_range(start='1970-01-01', end="2017-04-01 23:59:59", freq="MS"))[0].transform(lambda m : ((mtx.loc[(mtx["EQ"].isin(fsc)) & (mtx["START"] >= pd.to_datetime(m)) & (mtx["START"] <= pd.to_datetime(m) + MonthEnd(1))]).groupby(["ORG","LOC"])['HOURS'].agg(['mean', 'sum']).T.unstack())).stack().stack().stack().reset_index()
您将获得
level_0 level_1 LOC ORG 0
0 499 mean B 52 10.0
1 499 sum B 52 10.0
2 503 mean B 52 18.0
3 503 sum B 52 18.0
不确定该输出是否是您想要的,但是您可以执行以下操作:
new_df['mean'] = new_df[new_df['level_1'] == 'mean'][0]
new_df['sum'] = new_df[new_df['level_1'] == 'sum'][0]
new_df['sum'] = new_df['sum'].shift(-1)
new_df[~new_df['mean'].isna()].drop(columns=['level_1',0])
level_0 LOC ORG mean sum
0 499 B 52 10.0 10.0
2 503 B 52 18.0 18.0