我有一个数据框,我想在逻辑下方应用,以获得对该组进行分析的第一行组。
def mark_wakeup_source(df):
min_id = df['Astart'].idxmin()
df.loc[min_id, ["Reason", "Count", "CSwitch", "Used"]] = [df.loc[min_id, "type"],
len(df.index),
len(df[df['type'] == "Process"]),
df["Aduration"].sum()]
return df
以下是我调用apply函数并将其组合的方法。
df_t1 = df_t[df_t['type'] != 'Unknown'].copy()
df_t1['Reason'] = "None"
grouped = df_t1.groupby(["CPU", "index"])
df_t1 = grouped.apply(mark_wakeup_source)
df_t = df_t1.append(df_t[df_t['type'] == 'Unknown'])
我目前的数据中有29K +唯一组,处理时间约为140秒。我有比这个更大的数据,我需要优化它,并且没有线索如何去做。
我的数据在分组之前看起来像这样:
CPU State Start Stop pre_state next_state index Astart \
0 4 Active 0.015417 0.056283 C1 C1 1 0.015429
1 4 Active 0.015417 0.056283 C1 C1 1 0.015437
18 5 Active 0.015492 0.015499 C1 C1 2 0.015495
14 4 Active 0.015417 0.056283 C1 C1 1 0.019524
20 1 Active 0.019921 0.020071 C3 C3 1 0.019938
Astop Name type Count CSwitch Used Reason Aduration
0 0.015437 System Process 0 0 0 None 0.000008
1 0.032188 wpr.exe Process 0 0 0 None 0.016751
18 0.015498 System Process 0 0 0 None 0.000003
14 0.019727 ntoskrnl.exe DPC 0 0 0 None 0.000203
20 0.020064 System Process 0 0 0 None 0.000126
我尽可能减少了团体数量。 试过Numba,但这根本没有帮助。 基于我在代码下面尝试的许多其他答案,通过返回0而不是df,这需要〜180s:
def mark_wakeup_source(df, df_parent):
df_len = len(df.index)
min_id = df['Astart'].idxmin()
df_parent.loc[min_id, ["Reason", "Count", "CSwitch", "Used"]] =
[df.loc[min_id, "type"],
df_len,
len(df[df['type'] == "Process"]),
df["Aduration"].sum()]
return 0
用尽线索,寻找一些建议以最佳方式完成。
答案 0 :(得分:1)
从聚合函数字典开始。
f = {
'Astart' : [('Reason', 'idxmin')],
'type' : [
('Count', 'size'),
('CSwitch', lambda x: x.eq('Process').sum())
],
'Aduration' : [('Used', 'sum')]
}
接下来,query
+ groupby
并将f
传递给agg
。
v = df.query("type != 'Unknown'").groupby(['CPU', 'index']).agg(f)
v.columns = v.columns.droplevel(0)
v['Reason'] = df.loc[v['Reason'].values, 'type'].values
v
Reason Count CSwitch Used
CPU index
1 1 20 1 1 0.000126
4 1 0 3 2 0.016962
5 2 18 1 1 0.000003
请注意,在此使用agg
聚合数据的速度更快批次,因为它矢量化您的操作(这比类似循环的{{更快} { 1}}解决方案)。
答案 1 :(得分:1)
为了优化代码,我根据@ COLDSPEED的建议使用了:
df_min = grouped.agg({'Aduration': 'sum', 'type': 'count', 'Astart': 'min'}).reset_index()
df_min.rename(columns={'Aduration': "Used", 'type': 'Count', 'Astart': 'min'}, inplace=True)
df_with_proc = df_t1[df_t1['type'] == "Process"].groupby(["CPU", "index"]).agg({'type': 'count'}).reset_index()
df_with_proc.rename(columns={'type': 'CSwitch'}, inplace=True)
df_t1 = pd.merge(df_with_proc, df_t1, how="right", on=['CPU', 'index'])
df_t1 = pd.merge(df_min, df_t1, how="right", on=['CPU', 'index'])
这可以在同一数据帧上以0.2秒计算。