我有以下数据框:
df1
Rule 1 Rule 2 Rule 3 Rule 4 Rule 5 Rule 6
0 A == 'ABC'
1 B == 1234
2 C== 'ABC123' C== 'XYZ123'
3 D>= 20150101 D<= 20990101
4 O== '12.34.56' O== '24.65.12'
5 W>= -1.00 W<= 3000
6 P== '589qs'
我正在数据框上实现for循环:
for i in range(len(df1.index)):
answer = eval(df1.loc[i, 'Rule 1']) or eval(df1.loc[i, 'Rule 2']) or eval(df1.loc[i, 'Rule 3']) or eval(df1.loc[i, 'Rule 4']) or eval(df1.loc[i, 'Rule 5']) or eval(df1.loc[i, 'Rule 6'])
answer_list.append(answer)
如您所见,我正在使用eval()
函数,该函数评估数据帧中给定的条件并将布尔输出存储在变量中。列之间的关系应该是'OR'函数,而行之间的关系可以不是'OR'
问题在于数据帧太大,无法实现for循环,因为它花费了太多时间。
我正在寻找使用apply()
函数而不是for循环来减少运行时间,但似乎不知道该怎么做。
我尝试过的事情:
df1.apply(lambda x: answer_list.append((eval(x.values))), axis = 1)
很明显,它会产生错误,因为在这种情况下,x.values
将整个行作为一个序列。
在这种情况下,如何用apply()函数替换for循环?还是可以实施其他措施?
答案 0 :(得分:2)
创建自己的评估函数并应用它:
import pandas as pd
df = pd.DataFrame([['1 == 1', '3 == 3'], ['2 == 2', '4 == 4'], ['1 > 2', '5 > 6']], columns=['Rule1', 'Rule2'])
def my_eval_func(*args):
answer = False
for arg in args[0]:
answer = answer or eval(arg)
return answer
df['answer'] = df.apply(my_eval_func, axis=1)
print(df.head)
> Rule1 Rule2 answer
>0 1 == 1 3 == 3 True
>1 2 == 2 4 == 4 True
>2 1 > 2 5 > 6 False
答案 1 :(得分:1)
您可以使用“申请”和“按行评估”,例如:
answer_list = df.apply(lambda x: sum(eval(x[c]) for c in df.columns) > 0, axis=1).tolist()
您可以像字典一样访问系列行(代码中的x
),因此您可以创建自己的函数以提高代码的可读性,也可以像本例中那样创建lambda。 / p>
在apply中追加到列表确实可以正常工作,就像将列表作为理解打印在列表中一样,但是我发现它有点难看。尤其是当您无需附加即可直接获得结果时(因为可能应用了循环和附加)。