[英]How to apply a custom function to groups in a dask dataframe, using multiple columns as function input
[英]How to apply a function on a DataFrame Column using multiple rows and columns as input?
我有一系列事件,并基于一些变量(上一个命令,前一个/当前代码和前一个/当前状态),我需要决定哪个命令与该事件相关。
我实际上有一个按预期工作的代码,但它有点慢。 所以我尝试使用df.apply,但我认为不可能使用比当前元素更多的输入。 (代码从1开始,因为第一行始终是“开始”命令)
def mark_commands(df):
for i in range(1, len(df)):
prev_command = df.loc[i-1, 'Command']
prev_code, cur_code = df.loc[i-1, 'Code'], df.loc[i, 'Code']
prev_status, cur_status = df.loc[i-1, 'Status'], df.loc[i, 'Status']
if (prev_command == "end" and
((cur_code == 810 and cur_status in [10, 15]) or
(cur_code == 830 and cur_status == 15))):
df.loc[i, 'Command'] = "ignore"
elif ((cur_code == 800 and cur_status in [20, 25]) or
(cur_code in [810, 830] and cur_status in [10, 15])):
df.loc[i, 'Command'] = "end"
elif ((prev_code != 800) and
((cur_code == 820 and cur_status == 25) or
(cur_code == 820 and cur_status == 20 and
prev_code in [810, 820] and prev_status == 20) or
(cur_code == 830 and cur_status == 25 and
prev_code == 820 and prev_status == 20))):
df.loc[i, 'Command'] = "continue"
else:
df.loc[i, 'Command'] = "begin"
return df
这里有一个CSV格式的正确标记的样本(可以作为输入,因为唯一的区别是第一次开始后命令行上的所有内容都是空的):
Code,Status,Command
810,20,begin
810,10,end
810,25,begin
810,15,end
810,15,ignore
810,20,begin
810,10,end
810,25,begin
810,15,end
810,15,ignore
810,20,begin
800,20,end
810,10,ignore
810,25,begin
820,25,continue
820,25,continue
820,25,continue
820,25,continue
800,25,end
你的代码大部分是完美的(你可以使用df.iterrows()
,如果你的索引不是线性的,那么在for
循环中会更加防弹,但它不会改变速度)。
在广泛尝试使用df.apply
,我意识到由于您的"Command"
列不断从一行更新到另一行,因此存在致命流。 以下是行不通的,因为df
在某种程度上是“静态的”:
df['Command'] = df.apply(lambda row: mark_commands(row), axis=1)
最后,为了节省一些计算,如果你的if
, elif
语句直接进入下一次迭代,你可以在每次条件满足时插入一个continue
语句:
if (prev_command == "end" and ....) :
df.loc[i, 'Command'] = "ignore"
continue
话虽这么说,你的代码很棒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.