我想返回一个数组或其中的一个索引,其中包含numpy数组中哪些成员组合的总和为特定数字。
例如,如果我采用此数组并想找到其成员总计为7的所有组合:
import numpy as np
example = np.arange(4) + 1
example
>>> array([1, 2, 3, 4])
它将返回:
somefunction
>>> [[1,2,4], [3,4]]
或索引:
>>> [[0,1,2], [2,3]]
我可以想象使用itertools.combinations
的方法,尽管我想避免这种情况,因为我要使用的数据集已经有大约30,000个成员。考虑每种组合长度时,它的运行速度不够快。
有更快的方法吗?
编辑:有关其他信息,我没有必要使用30,000个成员的每种组合。例如,我将整数总计为〜1000,因此我需要<1000个成分-在我的情况下,列表成分的结尾数可能由100-400个成分组成。
答案 0 :(得分:2)
扩展评论而不是答案。根据数据的结构,列出具有给定总和的元素的所有组合可能是不可行的。但是,有一种有效的方法可以计算组合的数量。然后,您可以决定是否要尝试列出每个列表。
例如,使用0和10之间的10k个随机整数,我发现243905016604941663446994
个子集的总和为10-这是一个24位数字。如果您可以每纳秒列出一个组合,则将花费700万年。总计为1000
的30k个随机整数数组的数字应该大得多。
代码段,用于计算总计为数字的组合。
import numpy as np
import sys
example = np.arange(4) + 1
example_target = 7
# assuming all elemenst of arr are positive integers
def count_combs(arr, sum_):
arr = np.sort(arr)
sys.setrecursionlimit(100_000)
state_dict = {}
def state(i, j):
if (i, j) in state_dict:
return state_dict[(i, j)]
elif j < 0:
res = 0
elif j == 0:
res = 1
elif i == 0:
res = 1 if j == arr[i] else 0
else:
res = state(i - 1, j - arr[i]) + state(i - 1, j)
state_dict[(i, j)] = res
return res
return state(arr.shape[0] - 1, sum_)
# print(count_combs(example, example_target))
# prints 2
test_big = np.random.randint(0, 10, size=10000)
test_target = 10
def test():
print(count_combs(test_big, test_target))
if __name__ == "__main__":
test()
# e.g. 258364297793668558120414
答案 1 :(得分:0)
如果您介意itertools.combinations
,可以使用:
print([x for i in range(1,4) for x in itertools.combinations(example,i) if sum(x)==7])
输出:
[(3, 4), (1, 2, 4)]
如果要订购,请排序:
print(sorted([x for i in range(1,4) for x in itertools.combinations(example,i) if sum(x)==7]))
输出:
[(1, 2, 4), (3, 4)]
您说itertools.combinations
会很慢,但是除了itertools.combinations
之外,实际上没有其他有效的方法。