组合任意数量矩阵的每个列组合
Combining every column-combination of an arbitrary number of matrices
我正在想办法做某事 "reduction"
我有一个 varying 个大小为 varying 的矩阵,例如
1 2 2 2 5 6...70 70
3 7 8 9 7 7...88 89
1 3 4
2 7 7
3 8 8
9 9 9
.
.
44 49 49 49 49 49 49
50 50 50 50 50 50 50
87 87 88 89 90 91 92
我需要做的(我希望我解释得足够清楚)是将 任何可能的
来自这些矩阵的列 的组合,这意味着一列可能是
1
3
1
2
3
9
.
.
.
44
50
87
这将减少到
1
2
3
9
.
.
.
44
50
87
我之所以这样做是因为我需要找到最小的唯一组合列
我想要完成什么
对于那些感兴趣的人,我正在尝试找到最小的基因敲除集
禁用反应。这里,每个矩阵代表一个反应,列代表
会禁用该反应的基因。
该方法可以根据需要蛮力,因为这些矩阵很少变得非常大,
而且反应组合也不会很长
问题
我不能(据我所知)用任意数量的迭代器创建一个 for 循环,以及
矩阵(对禁用的反应)是任意的。
澄清
如果我有矩阵 A、B、C,列为 a1、a2...b1、b2...c1...cn 我需要什么
是列 [a1 b1 c1], [a1, b1, c2], ..., [a1 b1 cn] ... [an bn cn]
解决方案
由下方 提供。
他的回答的扩展,为了完整性
他的解决方案以
结束
MyProd = product(Array_of_ColGroups...)
哪个完成了工作
然后从他停下的地方继续
collection = collect(MyProd); #MyProd is an iterator
merged_cols = Array[] # the rows of 'collection' are arrays of arrays
for (i,v) in enumerate(collection)
# I apologize for this line
push!(merged_cols, sort!(unique(vcat(v...))))
end
# find all lengths so I can find which is the minimum
lengths = map(x -> length(x), merged_cols);
loc_of_shortest = find(broadcast((x,y) -> length(x) == y, merged_cols,minimum(lengths)))
best_gene_combos = merged_cols[loc_of_shortest]
好的,让我们看看我是否理解这一点。您有 n
个矩阵,并希望所有组合都与每个 n
矩阵中的一列相结合?如果是这样,Iterators 包中的 product()
(对于笛卡尔积)怎么样?
using Iterators
n = 3
Array_of_Arrays = [rand(3,3) for idx = 1:n] ## arbitrary representation of your set of arrays.
Array_of_ColGroups = Array(Array, length(Array_of_Arrays))
for (idx, MyArray) in enumerate(Array_of_Arrays)
Array_of_ColGroups[idx] = [MyArray[:,jdx] for jdx in 1:size(MyArray,2)]
end
MyProd = product(Array_of_ColGroups...)
这将创建一个迭代器对象,然后您可以遍历该对象以考虑列的特定组合。
tl;dr - 完整的解决方案:
# example matrices
a = rand(1:50, 8,4); b = rand(1:50, 10,5); c = rand(1:50, 12,4);
Matrices = [a,b,c];
toJagged(x) = [x[:,i] for i in 1:size(x,2)];
JaggedMatrices = [toJagged(x) for x in Matrices];
Combined = [unique(i) for i in JaggedMatrices[1]];
for n in 2:length(JaggedMatrices)
Combined = [unique([i;j]) for i in Combined, j in JaggedMatrices[n]];
end
Lengths = [length(s) for s in Combined];
Minima = findin(Lengths, min(Lengths...));
SubscriptsArray = ind2sub(size(Lengths), Minima);
ComboTuples = [((i[j] for i in SubscriptsArray)...) for j in 1:length(Minima)]
解释:
假设您有矩阵 a
和 b
a = rand(1:50, 8,4);
b = rand(1:50, 10,5);
将它们表示为锯齿状数组,列在前
A = [a[:,i] for i in 1:size(a,2)];
B = [b[:,i] for i in 1:size(b,2)];
使用列表理解连接所有列组合的行;当场删除重复项:
Combined = [unique([i;j]) for i in A, j in B];
您现在拥有 a 和 b 的所有列组合,作为已删除重复项的串联行。轻松找到长度:
Lengths = [length(s) for s in Combined];
如果您有两个以上的矩阵,请在 for 循环中迭代执行此过程,例如通过使用 Combined
矩阵代替 a
。例如如果你有一个矩阵 c
:
c = rand(1:50, 12,4);
C = [c[:,i] for i in 1:size(c,2)];
Combined = [unique([i;j]) for i in Combined, j in C];
一旦您将长度数组作为多维数组(与输入矩阵一样多的维度,其中每个维度的大小是每个矩阵中的列数),您可以找到对应于最低的列组合值(可能有不止一种组合),通过简单的 ind2sub
操作:
Minima = findin(Lengths, min(Lengths...));
SubscriptsArray = ind2sub(size(Lengths), Minima)
(例如,对于具有 3 个输入矩阵的随机 运行,我碰巧得到 4 个结果,最小长度为 19。ind2sub 的结果是 ([4,4,3,4,4],[3,3,4,5,3],[1,3,3,3,4])
您可以将其进一步转换为具有(有点难看)列表理解的 "Column Combination" 元组列表:
ComboTuples = [((i[j] for i in SubscriptsArray)...) for j in 1:length(Minima)]
# results in:
# 5-element Array{Tuple{Int64,Int64,Int64},1}:
# (4,3,1)
# (4,3,3)
# (3,4,3)
# (4,5,3)
# (4,3,4)
我正在想办法做某事 "reduction" 我有一个 varying 个大小为 varying 的矩阵,例如
1 2 2 2 5 6...70 70
3 7 8 9 7 7...88 89
1 3 4
2 7 7
3 8 8
9 9 9
.
.
44 49 49 49 49 49 49
50 50 50 50 50 50 50
87 87 88 89 90 91 92
我需要做的(我希望我解释得足够清楚)是将 任何可能的 来自这些矩阵的列 的组合,这意味着一列可能是
1
3
1
2
3
9
.
.
.
44
50
87
这将减少到
1
2
3
9
.
.
.
44
50
87
我之所以这样做是因为我需要找到最小的唯一组合列
我想要完成什么
对于那些感兴趣的人,我正在尝试找到最小的基因敲除集 禁用反应。这里,每个矩阵代表一个反应,列代表 会禁用该反应的基因。
该方法可以根据需要蛮力,因为这些矩阵很少变得非常大, 而且反应组合也不会很长
问题
我不能(据我所知)用任意数量的迭代器创建一个 for 循环,以及 矩阵(对禁用的反应)是任意的。
澄清
如果我有矩阵 A、B、C,列为 a1、a2...b1、b2...c1...cn 我需要什么 是列 [a1 b1 c1], [a1, b1, c2], ..., [a1 b1 cn] ... [an bn cn]
解决方案
由下方
他的回答的扩展,为了完整性
他的解决方案以
结束MyProd = product(Array_of_ColGroups...)
哪个完成了工作
然后从他停下的地方继续
collection = collect(MyProd); #MyProd is an iterator
merged_cols = Array[] # the rows of 'collection' are arrays of arrays
for (i,v) in enumerate(collection)
# I apologize for this line
push!(merged_cols, sort!(unique(vcat(v...))))
end
# find all lengths so I can find which is the minimum
lengths = map(x -> length(x), merged_cols);
loc_of_shortest = find(broadcast((x,y) -> length(x) == y, merged_cols,minimum(lengths)))
best_gene_combos = merged_cols[loc_of_shortest]
好的,让我们看看我是否理解这一点。您有 n
个矩阵,并希望所有组合都与每个 n
矩阵中的一列相结合?如果是这样,Iterators 包中的 product()
(对于笛卡尔积)怎么样?
using Iterators
n = 3
Array_of_Arrays = [rand(3,3) for idx = 1:n] ## arbitrary representation of your set of arrays.
Array_of_ColGroups = Array(Array, length(Array_of_Arrays))
for (idx, MyArray) in enumerate(Array_of_Arrays)
Array_of_ColGroups[idx] = [MyArray[:,jdx] for jdx in 1:size(MyArray,2)]
end
MyProd = product(Array_of_ColGroups...)
这将创建一个迭代器对象,然后您可以遍历该对象以考虑列的特定组合。
tl;dr - 完整的解决方案:
# example matrices
a = rand(1:50, 8,4); b = rand(1:50, 10,5); c = rand(1:50, 12,4);
Matrices = [a,b,c];
toJagged(x) = [x[:,i] for i in 1:size(x,2)];
JaggedMatrices = [toJagged(x) for x in Matrices];
Combined = [unique(i) for i in JaggedMatrices[1]];
for n in 2:length(JaggedMatrices)
Combined = [unique([i;j]) for i in Combined, j in JaggedMatrices[n]];
end
Lengths = [length(s) for s in Combined];
Minima = findin(Lengths, min(Lengths...));
SubscriptsArray = ind2sub(size(Lengths), Minima);
ComboTuples = [((i[j] for i in SubscriptsArray)...) for j in 1:length(Minima)]
解释:
假设您有矩阵 a
和 b
a = rand(1:50, 8,4);
b = rand(1:50, 10,5);
将它们表示为锯齿状数组,列在前
A = [a[:,i] for i in 1:size(a,2)];
B = [b[:,i] for i in 1:size(b,2)];
使用列表理解连接所有列组合的行;当场删除重复项:
Combined = [unique([i;j]) for i in A, j in B];
您现在拥有 a 和 b 的所有列组合,作为已删除重复项的串联行。轻松找到长度:
Lengths = [length(s) for s in Combined];
如果您有两个以上的矩阵,请在 for 循环中迭代执行此过程,例如通过使用 Combined
矩阵代替 a
。例如如果你有一个矩阵 c
:
c = rand(1:50, 12,4);
C = [c[:,i] for i in 1:size(c,2)];
Combined = [unique([i;j]) for i in Combined, j in C];
一旦您将长度数组作为多维数组(与输入矩阵一样多的维度,其中每个维度的大小是每个矩阵中的列数),您可以找到对应于最低的列组合值(可能有不止一种组合),通过简单的 ind2sub
操作:
Minima = findin(Lengths, min(Lengths...));
SubscriptsArray = ind2sub(size(Lengths), Minima)
(例如,对于具有 3 个输入矩阵的随机 运行,我碰巧得到 4 个结果,最小长度为 19。ind2sub 的结果是 ([4,4,3,4,4],[3,3,4,5,3],[1,3,3,3,4])
您可以将其进一步转换为具有(有点难看)列表理解的 "Column Combination" 元组列表:
ComboTuples = [((i[j] for i in SubscriptsArray)...) for j in 1:length(Minima)]
# results in:
# 5-element Array{Tuple{Int64,Int64,Int64},1}:
# (4,3,1)
# (4,3,3)
# (3,4,3)
# (4,5,3)
# (4,3,4)