我试图在Cython中实现一个NaN安全的洗牌过程,它可以沿着任意维多维矩阵的几个轴进行洗牌。在
在一维矩阵的简单情况下,可以使用Fisher–Yates算法简单地对所有非NaN值的索引进行洗牌:
def shuffle1D(np.ndarray[double, ndim=1] x):
cdef np.ndarray[long, ndim=1] idx = np.where(~np.isnan(x))[0]
cdef unsigned int i,j,n,m
randint = np.random.randint
for i in xrange(len(idx)-1, 0, -1):
j = randint(i+1)
n,m = idx[i], idx[j]
x[n], x[m] = x[m], x[n]
我想扩展这个算法来处理大的多维数组而不改变形状(对于这里没有考虑的更复杂的情况,这会触发一个副本)。为此,我需要去掉固定的输入维,这对于numpy数组和Cython中的memoryviews似乎都不可能。有解决办法吗?在
先谢谢你!在
下面的算法是基于切片的,其中不进行复制,它应该适用于任何
np.ndarray
。主要步骤是:np.ndindex()
用于遍历不同的多维索引,不包括属于要随机移动的轴的索引代码:
感谢@Veedrac的评论,这个答案使用了更多Cython功能。在
axis
存储值的内存地址C
有序数组创建副本。如果是Fortran
有序数组,ravel()
命令将返回一个副本。这可以通过创建另一个包含x
值的双指针数组来改进,可能会有一些缓存惩罚。。。在这个代码比基于切片的另一个代码至少快一个数量级。在
相关问题 更多 >
编程相关推荐