以下是需要针对性能进行优化的工作代码。
任务描述:在生成的组合列表(df)中,需要找到满足条件的组合:
1) 对于 listNumbers 的每个组合 - 必须匹配 df 中每行 2 到 3 个项目。
2) 对于 df 中的每一行,必须满足条件 1) 对于 listNumbers 中的至少一个组合
import pandas as pd
import numpy as np
import itertools as iter
import math as mt
import timeit
from functools import reduce
listNumbers = [[1,2,3,4,5], [2,3,5,6,7]]
df = pd.DataFrame(iter.combinations(range(1, 8), 5))
print(df)
containsMap = list(map(lambda x: df.isin(x).sum(1).between(2,3), listNumbers))
containsReduce = reduce(lambda f, x: f | x, containsMap)
print(df[containsReduce])
初始生成列表
0 1 2 3 4
0 1 2 3 4 5
1 1 2 3 4 6
2 1 2 3 4 7
3 1 2 3 5 6
4 1 2 3 5 7
5 1 2 3 6 7
6 1 2 4 5 6
7 1 2 4 5 7
8 1 2 4 6 7
9 1 2 5 6 7
10 1 3 4 5 6
11 1 3 4 5 7
12 1 3 4 6 7
13 1 3 5 6 7
14 1 4 5 6 7
15 2 3 4 5 6
16 2 3 4 5 7
17 2 3 4 6 7
18 2 3 5 6 7
19 2 4 5 6 7
20 3 4 5 6 7
最终筛选列表
0 1 2 3 4
0 1 2 3 4 5
1 1 2 3 4 6
2 1 2 3 4 7
5 1 2 3 6 7
6 1 2 4 5 6
7 1 2 4 5 7
8 1 2 4 6 7
9 1 2 5 6 7
10 1 3 4 5 6
11 1 3 4 5 7
12 1 3 4 6 7
13 1 3 5 6 7
14 1 4 5 6 7
17 2 3 4 6 7
18 2 3 5 6 7
19 2 4 5 6 7
20 3 4 5 6 7
在实际任务中,df中的组合数为range(1, 101),listNumbers中的条目数约为20。
熊猫的生活通常非常缓慢。而且,鉴于您的数字不会组合重复,最好使用集合来存储和比较数字集合。根据我的计算,有了它们,速度已经提高了几个数量级。
对于 range(1,8) timeit 显示从 5.14 ms 减少到 30.3 µs,即 超过 100 次。
PS我尝试了很大范围 - 根本没有任何改进,组合本身开始比其他代码花费更多的时间。也许在某个地方我仍然在列表中有额外的翻译,但似乎这里已经没有什么需要修复的了。是多线程做的。