我有一个大矩阵(大约80,000 X 60,000),我基本上想要加扰所有条目(即,独立地随机置换行和列)。
我相信如果我循环遍历列,并使用randperm随机置换每列,它将起作用。 (或者,我同样可以做行。)因为这涉及一个60K迭代的循环,我想知道是否有人可以建议更有效的选项?
我也一直在使用numpy / scipy,所以如果你知道python中的一个好选项,那也会很棒。
谢谢! 苏珊
感谢所有有思想的答案!更多信息:矩阵的行表示文档,每行中的数据是该文档的tf-idf权重的向量。每列对应于词汇表中的一个术语。我正在使用pdist来计算所有论文之间的余弦相似度。我想生成一组随机的论文来比较。
我认为只需置换列就行了,因为每篇论文都会被分配一组随机的术语频率。 (置换行只意味着重新排序论文。)正如Jonathan指出的那样,这样做的好处是不会制作整个矩阵的新副本,而且听起来就像其他选项一样。
答案 0 :(得分:4)
你应该能够{1}}矩阵到1×4800000000“数组”,reshape
,最后randperm
它回到80000×60000矩阵。 德尔>
这将需要在最坏的情况下复制48亿个条目3次。这可能效率不高。
编辑:实际上Matlab会自动使用线性索引,因此不需要第一个reshape
。刚
reshape
就足够了(因此减少了1次不必要的潜在复制)。
请注意,这假设您有一个密集矩阵。如果您有稀疏矩阵,则可以提取值,然后随机地将索引重新分配给它们。如果有非零条目,则最坏情况下只需要8N复制(描述一个条目需要3个数字)。
答案 1 :(得分:2)
我认为最好这样做:
import numpy as np
flat = matrix.ravel()
np.random.shuffle(flat)
您基本上将矩阵展平为列表,对列表进行混洗,然后从列表中重新构建矩阵。
答案 2 :(得分:0)
上面的两个解决方案都很棒,并且可以使用,但我相信两者都将涉及在完成工作时在内存中制作一个全新矩阵的全新副本。由于这是一个巨大的矩阵,这非常痛苦。对于MATLAB解决方案,我认为您可能会创建两个额外的临时副本,具体取决于重塑内部的工作方式。我认为你通过操作列在正确的轨道上,但问题是它只会沿着列进行争夺。但是,我相信如果你之后沿着行进行randperm,你最终会得到一个完全置换的矩阵。这样你只会创建临时变量,最坏的情况是80,000乘以1.是的,这是两个循环,每个循环有60,000和80,000次迭代,但内部无论如何都必须发生。算法必须至少访问每个内存位置两次。您可以通过编写一个完全就位的C MEX函数来执行更高效的算法,但我认为您不会这样做。