【发布时间】:2021-06-16 07:29:38
【问题描述】:
我有一个大矩阵(例如 100.000 x 100.000)。好在它只包含零和一,而且大部分都是零(它已经保存为布尔矩阵以节省一些 RAM)。现在我需要将矩阵的每一列与所有其他列相乘。原因是我需要检查是否至少有一行两列都具有非零元素(因此将结果向量相乘并求和以检查它是否为零)。例如假设我们有一个矩阵
| 1.column | 2.column | 3.column |
|---|---|---|
| 1 | 0 | 0 |
| 1 | 1 | 0 |
| 0 | 0 | 1 |
然后我需要比较所有列并检查是否至少有一行两列都为一。因此,比较第一列和第二列将返回 True,因为它们都是第二行中的一个。但是,比较第一列和第三列以及第二列第三列将导致 False,因为没有行的行都为一个。 显然,这可以使用 for 循环并遍历所有列来完成。但是速度不是很令人满意。我已经尝试过这样的 numba:
@njit(parallel=True)
def create_dist_arr(arr: np.array):
n = arr.shape[1]
dist_arr = np.zeros(shape=(n, n)) #, dtype=bool)
for i in prange(arr.shape[1]):
for j in prange(i, arr.shape[1]):
dist_greater_zero = calc_dist_graeter_than_zeros(arr[:, i], arr[:, j])
dist_arr[i][j] = dist_greater_zero
dist_arr[i][j] = dist_greater_zero
return skill_dist_arr
@njit
def calc_dist_graeter_than_zeros(ith_col, jth_col):
return np.sum(np.multiply(ith_col, jth_col)) != 0
zero_arr = np.zeros(shape=(2000, 6000), dtype=bool)
bool_dist_matrix = create_dist_arr(zero_arr)
但是尽管有 120gb 的 RAM 和 32 个内核,但在 10.000 x 10.000 矩阵左右时会变得非常慢。像这样尝试 scipy.spatial.distance.pdist 时更糟糕的是:
from scipy.spatial.distance import pdist
zero_arr = np.zeros(shape=(500, 500), dtype=bool)
bool_dist_matrix = pdist(zero_arr, lambda u, v: np.sum(np.multiply(u, v)) != 0)
是否有一些使用稀疏矩阵或其他不会永远使用的好而快速的解决方法?
提前谢谢你:)
【问题讨论】:
-
原因是我需要检查是否至少有一行两列都有非零元素无论我读了多少次我都没有明白你的意思吗?
-
举个例子:假设矩阵 A= [1 0 0]
-
@LaLeTo 修改 OP 而不是将其放入 cmets
-
是的,给我秒,我对stackoverflow来说太愚蠢了
-
矩阵有多密集(非零条目的比例?)如果矩阵非常稀疏,那么利用它很重要(这可以在内存使用量较低的情况下更快几个数量级)。创建稀疏矩阵(csc 或 csr 取决于操作)后,您可以使用此稀疏数据。这是一个关于稀疏矩阵和向量的最大值的示例,以给出一个可以实现的想法:stackoverflow.com/a/64920528/4045774
标签: python numpy matrix sparse-matrix numba