我有一个形状为 (4000, 3)
的numpy ndarray X
,其中 X
中的每个样本都是一个3D坐标(x,y,z) .
我有一个形状 (4000, 4000)
的scipy csr矩阵 nn_rad_csr
,这是从 sklearn.neighbors.radius_neighbors_graph(X, 0.01, include_self=True)
生成的最近邻居图 .
nn_rad_csr.toarray()[i]
是一个形状(4000,)稀疏向量,其二进制权重(0或1)与节点 X[i]
中最近邻居图中的边相关联 .
例如,如果 nn_rad_csr.toarray()[i][j] == 1
则 X[j]
在最近的相邻半径 X[i]
内,而值 0
则表示它不是邻居 .
我想做的是有一个函数 radius_graph_conv(X, rad)
,它返回一个数组 Y
,它是 X
,由它的邻居平均' values. I'我不知道如何利用CSR矩阵的稀疏性来有效地执行 radius_graph_conv
. 我在下面有两个简单的图形转换实现 .
import numpy as np
from sklearn.neighbors import radius_neighbors_graph, KDTree
def radius_graph_conv(X, rad):
nn_rad_csr = radius_neighbors_graph(X, rad, include_self=True)
csr_indices = nn_rad_csr.indices
csr_indptr = nn_rad_csr.indptr
Y = np.copy(X)
for i in range(X.shape[0]):
j, k = csr_indptr[i], csr_indptr[i+1]
neighbor_idx = csr_indices[j:k]
rad_neighborhood = X[neighbor_idx] # ndim always 2
Y[i] = np.mean(rad_neighborhood, axis=0)
return Y
def radius_graph_conv_matmul(X, rad):
nn_rad_arr = radius_neighbors_graph(X, rad, include_self=True).toarray()
# np.sum(nn_rad_arr, axis=-1) is basically a count of neighbors
return np.matmul(nn_rad_arr / np.sum(nn_rad_arr, axis=-1), X)
有一个更好的方法吗?使用knn图,它是一个非常简单的函数,因为邻居的数量是固定的,你可以只索引到X,但是使用基于半径或密度的最近邻图,你必须使用CSR,(或者一个数组数组,如果你使用kd树) .
1 回答
这是利用csr格式的直接方式 . 你的matmul解决方案可能会做类似的事情 . 但我们通过利用它是一个邻接矩阵来保存一个查找(来自
.data
属性);另外,diff
ing.indptr
应该比总计等量的1更有效 .