我有两个只包含 1 和 0 的矩阵:
A,形状 n x m。
B,形状 n x o。
从概念上讲,“n”行代表包含产品“m”并为客户位置“o”提供服务的设施。
我想计算由至少一个设施“n”提供服务的客户“o”和产品“m”的每种组合。
这不像简单求和那么容易,因为我没有将整个数据结构相加。相反,我将每个“o”和“m”组合至少具有设施(而不是总设施)的次数相加。
我通过循环 B 的列、广播乘法、对行求和,然后对每行的总和是否 > 0 进行条件检查求和,成功地完成了此操作。
然而,循环很糟糕,这感觉就像 numpy 可以以矢量化方式做的事情。我研究过 np.stack 和 np.meshgrid。似乎都不适合我。
关于是否/如何对其进行矢量化有什么聪明的想法吗?
这是我的循环解决方案。正确答案是145。
import numpy as np
A = np.array(
[[1., 0., 1., 1., 1., 0., 1., 1., 1., 1.],
[0., 0., 1., 1., 0., 1., 1., 0., 0., 1.],
[0., 1., 1., 0., 0., 1., 0., 0., 1., 1.],
[0., 0., 0., 0., 0., 1., 0., 1., 0., 0.],
[0., 0., 1., 1., 0., 0., 0., 0., 0., 1.]]
)
print(A.shape)
A
B = np.array(
[[0., 1., 0., 0., 1., 0., 1., 1., 0., 1., 0., 1., 1., 0., 1., 0., 0., 0., 1., 1.],
[1., 0., 0., 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0., 1., 1., 0., 0., 1., 1.],
[0., 1., 1., 0., 1., 0., 0., 1., 0., 0., 0., 1., 1., 1., 1., 0., 0., 1., 0., 0.],
[0., 1., 1., 1., 1., 0., 0., 1., 1., 1., 1., 1., 1., 0., 0., 0., 1., 0., 0., 0.],
[1., 1., 0., 1., 0., 0., 0., 0., 0., 1., 1., 1., 1., 0., 1., 0., 1., 1., 0., 1.]]
)
print(B.shape)
B
def count_conditions(A: np.ndarray, B: np.ndarray):
# Inputs are all 0 or 1.
assert np.all((A == 0) | (A == 1))
assert np.all((B == 0) | (B == 1))
running_total = 0
for col in range(B.shape[1]):
# Select column and broadcast multiply.
this_broadcast = A.T * B[:,col]
# Sum each row.
row_sums = np.sum(this_broadcast, axis=1)
# Count how many rows had at least one.
running_total += np.sum(row_sums > 0)
return running_total
result = count_conditions(A=A, B=B)
print(result)
assert result == 145
我认为你想要矩阵乘法:
out = (A.T @ B).astype(bool).sum()
或同等内容:
out = (A.T @ B > 0).sum()