Python中是否存在从n维numpy数组中采样并返回每个绘制的索引的函数。如果不是如何定义这样的功能?
E.g:
>>> probabilities = np.array([[.1, .2, .1], [.05, .5, .05]])
>>> print function(probabilities, draws = 10)
([1,1],[0,2],[1,1],[1,0],[0,1],[0,1],[1,1],[0,0],[1,1],[0,1])
我知道这个问题可以通过一维数组以多种方式解决。但是,我将处理大型的n维数组,并且不能仅仅为了进行单次绘制而重塑它们。
答案 0 :(得分:3)
您可以使用np.unravel_index
:
a = np.random.rand(3, 4, 5)
a /= a.sum()
def sample(a, n=1):
a = np.asarray(a)
choices = np.prod(a.shape)
index = np.random.choice(choices, size=n, p=a.ravel())
return np.unravel_index(index, dims=a.shape)
>>> sample(a, 4)
(array([2, 2, 0, 2]), array([0, 1, 3, 2]), array([2, 4, 2, 1]))
这将返回一个数组元组,每个维度为a
一个,每个长度为请求的样本数。如果您希望拥有一个形状(samples, dimensions)
的数组,请将return语句更改为:
return np.column_stack(np.unravel_index(index, dims=a.shape))
现在:
>>> sample(a, 4)
array([[2, 0, 0],
[2, 2, 4],
[2, 0, 0],
[1, 0, 4]])
答案 1 :(得分:2)
如果您的阵列在内存中是连续的,则可以更改阵列的shape
:
probabilities = np.array([[.1, .2, .1], [.05, .5, .05]])
nrow, ncol = probabilities.shape
idx = np.arange( nrow * ncol ) # create 1D index
probabilities.shape = ( 6, ) # this is OK because your array is contiguous in memory
samples = np.random.choice( idx, 10, p=probabilities ) # sample in 1D
rowIndex = samples / nrow # convert to 2D
colIndex = samples % ncol
array([2, 0, 1, 0, 2, 2, 2, 2, 2, 0])
array([1, 1, 2, 0, 1, 1, 1, 1, 1, 1])
请注意,由于您的数组在内存中是连续的,reshape
也会返回一个视图:
In [53]:
view = probabilities.reshape( 6, -1 )
view[ 0 ] = 9
probabilities[ 0, 0 ]
Out[53]:
9.0