我在numpy数组中有大量独立的平行水平线段。每个段都有一个起点和终点(x坐标)和一个值(y坐标)。这些段的长度不必相同(长度=结束-开始)。
一个指定段的示例矩阵,每行一个段,如下所示:
Start End Value
0 10 4
5 19 3
6 25 2
7 16 1
12 21 5
在代码中
A = np.array([[0,10,4],
[5,19,3],
[6,25,2],
[7,16,1],
[12,21,5]])
我想弄清楚线段上的运行最大值。也就是说,在上面的示例中,对于x在[0,25)范围内,我想要相应的max y。与示例相对应的示例输出为
Start End Max
0 10 4
10 12 3
12 21 5
21 25 2
我可以在for循环中执行此操作,但这很慢,因为我有成千上万的段。我似乎无法想到一种矢量化方法。有人可以吗?
循环代码示例:
x = np.arange(np.min(A[:,0]), np.max(A[:,1]))
maxes = np.zeros((x.shape[0], 2))
maxes[:,0] = x
maxes[:,1] = -np.inf
for a in A:
ix = (x >= a[0]) & (x < a[1]) & (maxes[:,1] < a[2])
maxes[ix,1] = a[2]
与上面的输出示例相反,此代码输出一个数组,该数组对范围内的每个x都有一行。两者都很好(并且相当)。
答案 0 :(得分:1)
您可以将booleans
的数组用于索引数组。这意味着您可以一次根据条件检查所有坐标,然后用结果索引值列(A[2]
)。从您的示例结果中,我认为不应该包含线段的端点,因此以下代码:
import numpy as np
A = np.array(
[[0,10,4],
[5,19,3],
[6,25,2],
[7,16,1],
[12,21,5]]
)
ranges = np.array([
[0,10], [10,12], [12,21], [21,25]
])
for xmin,xmax in ranges:
print(xmin,xmax, np.max(A[~np.logical_or(A[:,1]<=xmin, A[:,0]>=xmax),2]))
再现您想要的结果:
0 10 4
10 12 3
12 21 5
21 25 2
答案 1 :(得分:1)
您可以使用布尔数组确定空间中的给定点是否在给定的线段中。该布尔数组可以与段值相乘以生成一个数组,其中行上的每个点都有一个段值向量,并且如果段不包括该点,则将该段的值清零。从那里可以沿单个轴应用数组的tools.jar
方法。
max