我正在尝试使用numpy
在矩阵中查找行的配置,以使对行的列求和将得到相同的值。例如,对于矩阵/数组
[[0,0,0,1],
[1,0,1,0],
[1,1,0,0],
[0,1,0,0]]
我想将第一行,第二行和最后一行作为输出,因为
0,0,0,1
1,0,1,0
0,1,0,0 +
-------
= 1,1,1,1
numpy
中是否有任何工具可以帮助我实现这一目标? 最佳答案
一种解决方案是枚举行的幂集,然后检查每个可能的行子集的求和条件。对于具有大量行的矩阵,这可能会非常慢。
使用标准itertools配方进行功率设置:
from itertools import chain, combinations
def powerset(iterable):
xs = list(iterable)
return chain.from_iterable(combinations(xs, n) for n in range(len(xs) + 1))
然后我展示了一个包含一些综合数据的工作示例:
In [79]: data
Out[79]:
array([[0, 1, 1],
[0, 0, 1],
[1, 0, 1],
[0, 1, 1],
[0, 0, 0],
[0, 1, 0],
[1, 1, 1],
[1, 1, 0],
[1, 1, 1],
[0, 1, 0]], dtype=int32)
In [80]: def is_constant(array):
...: return (array == array[0]).all()
...:
In [81]: solution = []
In [82]: for candidate in powerset(range(len(data))):
...: if candidate and is_constant(data[candidate, :].sum(axis=0)):
...: solution.append(candidate)
...:
例如,其中显示:
In [83]: solution
Out[83]:
[(4,),
(6,),
(8,),
(1, 7),
(2, 5),
(2, 9),
(4, 6),
(4, 8),
(6, 8),
(0, 2, 7),
(1, 4, 7),
(1, 6, 7),
(1, 7, 8),
(2, 3, 7),
(2, 4, 5),
(2, 4, 9),
(2, 5, 6),
(2, 5, 8),
(2, 6, 9),
(2, 8, 9),
(4, 6, 8),
(0, 2, 4, 7),
(0, 2, 6, 7),
(0, 2, 7, 8),
(1, 2, 5, 7),
(1, 2, 7, 9),
(1, 4, 6, 7),
(1, 4, 7, 8),
(1, 6, 7, 8),
(2, 3, 4, 7),
(2, 3, 6, 7),
(2, 3, 7, 8),
(2, 4, 5, 6),
(2, 4, 5, 8),
(2, 4, 6, 9),
(2, 4, 8, 9),
(2, 5, 6, 8),
(2, 6, 8, 9),
(0, 2, 4, 6, 7),
(0, 2, 4, 7, 8),
(0, 2, 6, 7, 8),
(1, 2, 4, 5, 7),
(1, 2, 4, 7, 9),
(1, 2, 5, 6, 7),
(1, 2, 5, 7, 8),
(1, 2, 6, 7, 9),
(1, 2, 7, 8, 9),
(1, 4, 6, 7, 8),
(2, 3, 4, 6, 7),
(2, 3, 4, 7, 8),
(2, 3, 6, 7, 8),
(2, 4, 5, 6, 8),
(2, 4, 6, 8, 9),
(0, 2, 4, 6, 7, 8),
(1, 2, 4, 5, 6, 7),
(1, 2, 4, 5, 7, 8),
(1, 2, 4, 6, 7, 9),
(1, 2, 4, 7, 8, 9),
(1, 2, 5, 6, 7, 8),
(1, 2, 6, 7, 8, 9),
(2, 3, 4, 6, 7, 8),
(1, 2, 4, 5, 6, 7, 8),
(1, 2, 4, 6, 7, 8, 9)]
我们可以针对以下几种情况验证解决方案:
In [84]: data[(1, 2, 4, 6, 7, 8, 9), :].sum(axis=0)
Out[84]: array([4, 4, 4])
In [85]: data[(0, 2, 4, 6, 7), :].sum(axis=0)
Out[85]: array([3, 3, 3])
要将其扩展为更特定的用例,可以使用
itertools.combinations
生成仅具有一定大小的子集,例如恰好2行或恰好3行的子集,等等。或者,您也可以从示例中给出的结果集中过滤掉不需要的结果(例如一次由一行组成的琐碎解决方案)。
注意,您可以简化
powerset
的函数定义(我使用的实际上是取自有关itertools配方的Python文档)。您可以传递一个整数并直接跳过以返回最终的chain.from_iterable
结果,然后修改以仅传递len(data)
作为powerset
的参数,而不是传递一个转换为列表的可迭代对象,像这样:from itertools import chain, combinations
def powerset(N):
"""Power set of integers {0, ..., N-1}."""
xs = list(range(N))
return chain.from_iterable(combinations(xs, n) for n in range(N + 1))
...
for candidate in powerset(len(data)):
...
关于python - 使用Numpy查找数组中行的组合,以使每一列求和为相同值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50317305/