我有两个形状为m
的incidies数组。我需要取一个形状为m x n
的数组的指数之间的值的平均值。可以不遍历每一行来完成这个任务吗?最快的方法是什么?
idx0 = np.array([1, 3, 2, 5])
idx1 = np.array([5, 8, 6, 7])
d = np.array([[1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8,9], [1,2,3,4,5,6,7,8,9]])
预期结果:
<< d[np.arange(d.shape[0]), idx0:idx1]
>> np.array([3.5, 6, 4.5, 6.5])
我发现的最好的方法是列表解析或使用numba的for循环,但这似乎是一个常见的问题?谢谢。
3条答案
按热度按时间txu3uszq1#
在您的情况下,您仍然需要从
idx0
和idx1
中获取索引的成对范围的切片。zip
+slice
是一个简单的方法:j13ufse22#
如果你使用
d.ravel()
而不是d
,事情会更容易,因为现在你可以使用np.add.reduceat
找到元素的和,并直接计算平均值。d.ravel()
中对应于idx0
和idx1
的线性索引为要获得要求和的范围的线性索引,可以执行以下操作
你想要一个1D数组的原因是,如果最后一个元素等于
d.size
,你需要能够删除它,因为np.add.reduceat
不接受超过数组末尾的索引:最后一个操作不复制数据:它只是创建了一个少了一个元素的视图。
现在可以直接求和:
需要每隔一个元素取一次,因为
idx1
的第n个元素与idx0
的第n+1个元素之间的和也存在于和中。现在,您可以通过每个段的长度进行归一化:
TL;DR
czfnxgou3#
另一种方法是屏蔽而不是索引。首先创建遮罩:
初始数组创建时多了一列,以适应
idx1
包含位于d.size[1]
的元素的情况。有许多方法你可以采取前进。
1.第一个可能是最简单的:使用掩码数组:
1.另一种方法是将数据预乘以掩码并计算自己的总和:
1.第三种方法是应用掩码并使用
np.add.reduceat
,类似于另一个答案的建议,但在掩码数据上,这避免了添加不必要的数字: