我需要(快速)稀薄一个矩阵。
Rarefaction - 将丰度矩阵转换为均匀的采样深度。
在这个例子中,每一行都是一个样本,采样深度是该行的总和。我想通过min(rowsums(matrix))样本对矩阵进行随机采样(有替换)。
假设我有一个矩阵:
>>> m = [ [0, 9, 0],
... [0, 3, 3],
... [0, 4, 4] ]
Run Code Online (Sandbox Code Playgroud)
min(rowsums(matrix))稀疏函数按替换次数(在本例中为 6)逐行随机采样。
>>> rf = rarefaction(m)
>>> rf
[ [0, 6, 0], # sum = 6
[0, 3, 3], # sum = 6
[0, 3, 3] ] # sum = 6
Run Code Online (Sandbox Code Playgroud)
结果是随机的,但行总和始终相同。
>>> rf = rarefaction(m)
>>> rf
[ [0, 6, 0], # sum = 6
[0, 2, 4], # sum = 6
[0, 4, 2], ] # sum = 6
Run Code Online (Sandbox Code Playgroud)
PyCogent有一个函数可以逐行执行此操作,但在大型矩阵上速度非常慢。
我感觉 Numpy 中有一个函数可以做到这一点,但我不确定它会被称为什么。
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
Run Code Online (Sandbox Code Playgroud)
例子:
>>> 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]])
Run Code Online (Sandbox Code Playgroud)
干杯,大卫
| 归档时间: |
|
| 查看次数: |
1370 次 |
| 最近记录: |