ise*_*arn 2 combinations iterator for-loop julia
我试图找出一种方法来做某种"减少"我有不同数量的不同大小的矩阵,例如
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
Run Code Online (Sandbox Code Playgroud)
我需要做的事情(我希望我能够清楚地解释这一点)是将这些矩阵中任何可能的列组合起来,这意味着一列可能是
1
3
1
2
3
9
.
.
.
44
50
87
Run Code Online (Sandbox Code Playgroud)
哪个会降低到
1
2
3
9
.
.
.
44
50
87
Run Code Online (Sandbox Code Playgroud)
我之所以这样做是因为我需要找到最小的唯一组合列
我想要完成什么?
对于那些感兴趣的人,我正试图找到最小的基因敲除来禁用反应.在这里,每个矩阵代表一个反应,列代表将禁用该反应的基因的指数.
该方法可以根据需要作为强力,因为这些基质很少变得非常大,并且反应组合也不会很长
问题
我不能(据我所知)使用任意数量的迭代器创建一个for循环,并且矩阵的数量(禁用的反应)是任意的.
澄清
如果我的矩阵A,B,C有列a1,a2 ... b1,b2 ... c1 ... cn我需要的是列[a1 b1 c1],[a1,b1,c2],.. .,[a1 b1 cn] ... [an bn cn]
解决方案 由Michael Ohlrogge提供.
为了完整性,扩展他的答案
他的解决方案以
MyProd = product(Array_of_ColGroups...)
Run Code Online (Sandbox Code Playgroud)
哪个完成了工作
并从他离开的地方继续前行
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]
Run Code Online (Sandbox Code Playgroud)
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)]
Run Code Online (Sandbox Code Playgroud)
说明:
假设你有矩阵a和b
a = rand(1:50, 8,4);
b = rand(1:50, 10,5);
Run Code Online (Sandbox Code Playgroud)
将它们表示为锯齿状数组,首先是列
A = [a[:,i] for i in 1:size(a,2)];
B = [b[:,i] for i in 1:size(b,2)];
Run Code Online (Sandbox Code Playgroud)
使用列表推导来连接所有列组合的行; 当场删除重复项:
Combined = [unique([i;j]) for i in A, j in B];
Run Code Online (Sandbox Code Playgroud)
您现在拥有a和b的所有列组合,因为删除了重复项的连续行.轻松找到长度:
Lengths = [length(s) for s in Combined];
Run Code Online (Sandbox Code Playgroud)
如果您有两个以上的矩阵,请在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];
Run Code Online (Sandbox Code Playgroud)
将Lengths数组作为多维数组(与输入矩阵一样多的维度,其中每个维度的大小是每个矩阵中的列数),您可以找到与最低值对应的列组合(可能很好)通过简单的ind2sub操作:多个组合):
Minima = findin(Lengths, min(Lengths...));
SubscriptsArray = ind2sub(size(Lengths), Minima)
Run Code Online (Sandbox Code Playgroud)
(例如,对于具有3个输入矩阵的随机运行,我碰巧得到4个结果,最小长度为19. ind2sub的结果是 ([4,4,3,4,4],[3,3,4,5,3],[1,3,3,3,4])
您可以将其进一步转换为"列组合"元组列表,其中包含(有些难看)列表理解:
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)
Run Code Online (Sandbox Code Playgroud)