【发布时间】:2020-08-15 23:59:44
【问题描述】:
我有一个可以完全矢量化的问题,但我没有足够的空间,所以我正在尝试使用 numpy 的 apply_along_axis() 的一半解决方案。
(注意:这是一个说明问题核心的玩具示例。换句话说,我不是在寻找一个 numpy 或 scipy 函数来完成这里的函数正在做的事情——它不是真正的函数,只是一个很容易说明的。)
我想做的是找出一种方法来访问每次迭代时传递的轴的索引。
假设我们采用了一个 4 x 4 矩阵:
M = np.array(([0,0,1,1], [1,1,0,1], [1,0,1,0], [0,0,1,1]))
M
array([[0, 0, 1, 1],
[1, 1, 0, 1],
[1, 0, 1, 0],
[0, 0, 1, 1]])
并且想要计算每一列相对于其他每一列的成对按位逻辑和,但为了节省(大量)时间,我们只计算列 i,j 其中 j > i 的索引(这样我们最终用三角矩阵)。
在 pandas 中,我可以使用 apply() 轻松完成此操作,但对于我的目的来说它太慢了。
我知道 scikit-learn 中有成对函数,但请假设这些不适合我的目的(我的函数比这个玩具更复杂)
如果我要使用 numpy 的 apply_long_axis(),我只能解决如何比较所有 i,j 和 j,i,而不是前面描述的小问题。
这是我的解决方案:
def intersections_np(col, M):
col = col[:,np.newaxis]
intersection = (M & col).sum(0)
return(intersection)
result_np = np.apply_along_axis(intersections_np, arr = M, axis = 0, M = M)
result_np
array([[2, 1, 1, 1],
[1, 1, 0, 1],
[1, 0, 3, 2],
[1, 1, 2, 3]], dtype=int32)
但我真正想做的是:
def intersections_np(col, M):
col = col[:,np.newaxis]
start_index = <index_of_current_column> + 1
other_cols = M[:,start_index:]
intersection = (other_cols & col).sum(0)
<possible padding of the array with nans here>
return(intersection)
result_np = np.apply_along_axis(intersections_np, arr = M, axis = 0, M = M)
然后返回:
result_np
array([[nan, nan, nan, nan],
[1, nan, nan, nan],
[1, 0, nan, nan],
[1, 1, 2, nan]], dtype=int32)
有没有人知道这样的事情可以做吗?
谢谢
【问题讨论】:
-
apply_along 不是速度工具。如果不方便,请不要浪费时间尝试使其发挥作用。
标签: python performance numpy vectorization