我需要(快速)稀疏矩阵。
稀疏 - 将丰度矩阵转换为均匀采样深度。
在此示例中,每行都是一个样本,采样深度是行的总和。我想通过min(rowsums(matrix))
样本随机抽样(替换)矩阵。
假设我有一个矩阵:
>>> m = [ [0, 9, 0],
... [0, 3, 3],
... [0, 4, 4] ]
稀疏函数逐行随机抽样,替换min(rowsums(matrix))
次(在这种情况下为6)。
>>> rf = rarefaction(m)
>>> rf
[ [0, 6, 0], # sum = 6
[0, 3, 3], # sum = 6
[0, 3, 3] ] # sum = 6
结果是随机的,但行总和始终相同。
>>> rf = rarefaction(m)
>>> rf
[ [0, 6, 0], # sum = 6
[0, 2, 4], # sum = 6
[0, 4, 2], ] # sum = 6
PyCogent有一个逐行执行此功能的函数,但在大型矩阵中它非常慢。
我觉得Numpy中有一个功能可以做到这一点,但我不确定它会被称为什么。
答案 0 :(得分:3)
import numpy as np
from numpy.random import RandomState
def rarefaction(M, seed=0):
prng = RandomState(seed) # reproducible results
noccur = np.sum(M, axis=1) # number of occurrences for each sample
nvar = M.shape[1] # number of variables
depth = np.min(noccur) # sampling depth
Mrarefied = np.empty_like(M)
for i in range(M.shape[0]): # for each sample
p = M[i] / float(noccur[i]) # relative frequency / probability
choice = prng.choice(nvar, depth, p=p)
Mrarefied[i] = np.bincount(choice, minlength=nvar)
return Mrarefied
示例:
>>> M = np.array([[0, 9, 0], [0, 3, 3], [0, 4, 4]])
>>> M
array([[0, 9, 0],
[0, 3, 3],
[0, 4, 4]])
>>> rarefaction(M)
array([[0, 6, 0],
[0, 2, 4],
[0, 3, 3]])
>>> rarefaction(M, seed=1)
array([[0, 6, 0],
[0, 4, 2],
[0, 3, 3]])
>>> rarefaction(M, seed=2)
array([[0, 6, 0],
[0, 3, 3],
[0, 3, 3]])
干杯, 的Davide
答案 1 :(得分:1)
我认为问题并不完全清楚。我想稀疏矩阵可以给出从原始矩阵的每个系数中得到的样本数量吗?
查看链接中的代码,可能会加快速度。在转置矩阵上操作并重写链接代码以对列而不是行进行操作。因为这样可以让你的处理器缓存它更好地采样的值,即内存中的跳转更少。
其余的就像我一样,使用numpy(并不一定意味着这是最有效的方式)。
如果你需要它更快,你可以尝试用C ++编写函数代码并用scipy.weave将它包含到你的python中。在C ++中,我会寻找每一行并构建一个位置> 0的查找表,生成min(rowsums(matrix))
整数,其范围等于查找表中的项目数。我会累积查找表中每个位置的绘制频率,然后将这些数字放回到数组中的正确位置。该代码应该只是几行。