【问题标题】:Numpy - group data into sum valuesNumpy - 将数据分组为总和值
【发布时间】:2013-10-02 14:55:23
【问题描述】:

假设我有一个值数组:

a = np.array([1,5,4,2,4,3,1,2,4])

和三个“总和”值:

b = 10
c = 9
d = 7

有没有办法将a 中的值分组为一组值,其中值组合等于 b、c 和 d?例如:

b: [5,2,3]
c: [4,4,1]
d: [4,2,1]

b: [5,4,1]
c: [2,4,3]
d: [4,2,1]

b: [4,2,4]
c: [5,4]
d: [1,1,2,3]

请注意,bcd 的总和应保持不变 (==26)。也许这个操作已经有了名字?

【问题讨论】:

  • 听起来您正在尝试解决“背包问题”(或其变体):en.wikipedia.org/wiki/Knapsack_problem
  • 类似的,我称之为“多重背包问题”。例如。有多少种方法可以把你的东西装进三个背包(成本不是问题)。
  • 所以这是一个搜索问题,而不是数字(numpy)问题。与大多数搜索问题一样,有一种蛮力解决方案和各种策略(通常是启发式的)来修剪死端分支。

标签: python arrays numpy set grouping


【解决方案1】:

这是一个使用 itertools 的简单实现

from itertools import chain, combinations

def group(n, iterable):
    s = list(iterable)
    return [c for c in chain.from_iterable(combinations(s, r)
                                           for r in range(len(s)+1))
            if sum(c) == n]

group(5, range(5))

产量

[(1, 4), (2, 3), (0, 1, 4), (0, 2, 3)]

注意,对于大型列表,这可能会非常慢,因为我们实际上是在构建和过滤该列表的幂集。


你可以用这个

sum_vals = [10, 9, 7]
a = [1, 5, 4, 2, 4, 3, 1, 2, 4]

map(lambda x: group(x, a), sum_vals)

然后zip他们在一起。

【讨论】:

  • 这不满足a中的每个值只能归为一组的隐含条件。
  • @askewchan,你是对的。但我认为这可能是一个很好的起点。我一直在玩弄使用np.unique(group(b,a)),然后在使用group(c,a)group(d,a) 的输出进行测试后以某种方式进行修剪。不过还没有成功。
  • 是的,它缺少的只是最后的过滤器,用于检查两个集合是否相等。 np.unique 是不够的,因为虽然顺序无关紧要,但每个条目的计数却很重要。你可以比较他们的bincounts。
  • 这应该可以工作:filter(lambda row: np.all(np.bincount(np.concatenate(row)) == np.bincount(a)), zip(*map(lambda x: group(x, a), sum_vals)))
  • 但实际上,您的原始输出也不完整。它没有@atomh33ls 找到的第二个或第三个输出,但它确实找到了@atomh33ls 没有找到的新输出:((4, 2, 4), (5, 3, 1), (1, 2, 4))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-20
  • 2020-02-29
  • 1970-01-01
  • 2020-03-02
  • 2015-06-19
  • 1970-01-01
相关资源
最近更新 更多