这个问题与 my previous question 相关。我有以下数据框:
df =
QUEUE_1 QUEUE_2 DAY HOUR TOTAL_SERVICE_TIME TOTAL_WAIT_TIME EVAL
ABC123 DEF656 1 7 20 30 1
ABC123 1 7 22 32 0
DEF656 ABC123 1 8 15 12 0
FED456 DEF656 2 8 15 16 1
我需要获得以下数据帧(它类似于我在上一个问题中想要获得的数据帧,但在这里我需要添加 2 个额外的列
AVG_COUNT_PER_DAY_HOUR
和 AVG_PERCENT_EVAL_1
)。QUEUE HOUR AVG_TOT_SERVICE_TIME AVG_TOT_WAIT_TIME AVG_COUNT_PER_DAY_HOUR AVG_PERCENT_EVAL_1
ABC123 7 21 31 1 50
ABC123 8 15 12 0.5 100
DEF656 7 20 30 0.5 100
DEF656 8 15 14 1 50
FED456 7 0 0 0 0
FED456 8 15 14 0.5 100
AVG_COUNT_PER_DAY_HOUR
列应包含按 HOUR
分组的几天内相应 DAY
值的平均计数 (QUEUE
)。例如,在 df
中,在 ABC123
的情况下,HOUR
1 的 DAY
7 出现 2 次,DAY
2 的 HOUR
7 出现 0 次。因此平均值为 1。同样的逻辑应用于 DAY
8。它出现 1 次DAY
1 次和 ABC123
2 中 AVG_PERCENT_EVAL_1
的 0 次。因此平均值为 0.5。EVAL
列应包含 QUEUE
在小时内等于 1 的百分比,按 ABC123
分组。例如,在 EVAL
的情况下,当 HOUR
为 7 时,HOUR
一次等于 1。当 AVG_PERCENT_EVAL_1
为 7 时,ABC123
也一次等于 0。因此,AVG_COUNT_PER_DAY_HOUR
对于 AVG_PERCENT_EVAL_1
和小时 7 时为 50。我使用这种方法:
df = pd.lreshape(aa, {'QUEUE': df.columns[df.columns.str.startswith('QUEUE')].tolist()})
piv_df = df.pivot_table(index=['QUEUE'], columns=['HOUR'], fill_value=0)
result = piv_df.stack().add_prefix('AVG_').reset_index()
我一直在添加列
AVG_COUNT_PER_DAY_HOUR
和 .apply(pd.value_counts, 1).notnull().groupby(level=0).sum().astype(int)
。例如,要添加列 AVG_PERCENT_EVAL_1
我想使用 [df.EVAL==1].agg({'EVAL' : 'count'})
,而计算 ojit_code 我想使用 ojit_code 。但是,不知道如何将其合并到我当前的代码中以获得正确的解决方案。更新:
也许更容易采用这种解决方案来解决我在这些问题中的需要:
result = pd.lreshape(df, {'QUEUE': ['QUEUE_1','QUEUE_2']})
mux = pd.MultiIndex.from_product([result.QUEUE.dropna().unique(),
result.dropna().DAY.unique(),
result.HOUR.dropna().unique(), ], names=['QUEUE','DAY','HOUR'])
print (result.groupby(['QUEUE','DAY','HOUR'])
.mean()
.reindex(mux, fill_value=0)
.add_prefix('AVG_')
.reset_index())
最佳答案
步骤:
1) 计算 AVG_COUNT_PER_DAY_HOUR :
在 pd.crosstab()
的帮助下,计算按 QUEUE 分组的 HOUR w.r.t DAYS 的不同计数(以便我们获得缺失天数的案例)。stack
DF
以便之前作为分层列的一部分的 HOUR 现在被定位为索引,只留下 DAYS 作为列。我们在用 0 填充 NaNs
后按列取平均值。
2) 计算 AVG_PERCENT_EVAL_1:
在获得枢轴框架(与之前相同)以及平均值只会给我们百分比变化的事实之后,因为它们本质上只是二进制(1/0),我们只需从这个 DF
中获取 EVAL 并将其结果乘以 100在旋转自身时计算平均值(默认 agg
= np.mean
)。
最后,我们加入所有这些框架。
与链接帖子中的相同:
df = pd.lreshape(df, {'QUEUE': df.columns[df.columns.str.startswith('QUEUE')].tolist()})
piv_df = df.pivot_table(index='QUEUE', columns='HOUR', fill_value=0).stack()
avg_tot = piv_df[['TOTAL_SERVICE_TIME', 'TOTAL_WAIT_TIME']].add_prefix("AVG_")
附加部分:
avg_cnt = pd.crosstab(df['QUEUE'], [df['DAY'], df['HOUR']]).stack().fillna(0).mean(1)
avg_pct = piv_df['EVAL'].mul(100).astype(int)
avg_tot.join(
avg_cnt.to_frame("AVG_COUNT_PER_DAY_HOUR")
).join(avg_pct.to_frame("AVG_PERCENT_EVAL_1")).reset_index()
avg_cnt
看起来像:QUEUE HOUR
ABC123 7 1.0
8 0.5
DEF656 7 0.5
8 1.0
FED456 7 0.0
8 0.5
dtype: float64
avg_pct
看起来像:QUEUE HOUR
ABC123 7 50
8 0
DEF656 7 100
8 50
FED456 7 0
8 100
Name: EVAL, dtype: int32
关于python - 如何将具有平均百分比和平均计数的列添加到数据框中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41938772/