我正试图想办法做一些“减少” 我有一个变化的变化大小的矩阵数,例如
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] ... [a bn cn]
解决方案 礼貌为Michael Ohlrogge以下。
为了完整性,扩展他的答案
他的解决方案以
结束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]
答案 0 :(得分:5)
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];
一旦将Lengths数组作为多维数组(与输入矩阵一样多的维度,其中每个维度的大小是每个矩阵中的列数),您可以找到与最低值对应的列组合(可以通过简单的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])
您可以将其进一步转换为&#34;列组合&#34;具有(有点难看)列表理解的元组:
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)
答案 1 :(得分:3)
好的,让我们看看我是否理解这一点。您有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...)
这将创建一个迭代器对象,然后您可以循环以考虑列的特定组合。