我正在尝试构建一个返回数组元素子集的乘积的函数。基本上我想构建一个prod_by_group执行此操作的函数:
values = np.array([1, 2, 3, 4, 5, 6])
groups = np.array([1, 1, 1, 2, 3, 3])
Vprods = prod_by_group(values, groups)
Run Code Online (Sandbox Code Playgroud)
结果Vprods应该是:
Vprods
array([6, 4, 30])
Run Code Online (Sandbox Code Playgroud)
对于元素之和,这里有一个很好的答案,我认为它应该类似于: /sf/answers/307121741/
我尝试采取log第一个,然后sum_by_group,然后exp,但遇到了数字问题。
对于按组排列的元素的最小和最大数量,这里还有一些其他类似的答案: /sf/answers/603621791/
编辑:感谢您的快速解答!我正在尝试它们。我应该补充一点,我希望它尽可能快(这就是我试图以某种矢量化方式将其放入 numpy 的原因,就像我给出的示例一样)。
编辑:我评估了迄今为止给出的所有答案,最好的答案由下面的 @seberg 给出。这是我最终使用的完整功能:
def prod_by_group(values, groups):
order = np.argsort(groups)
groups = groups[order]
values = values[order]
group_changes = np.concatenate(([0], np.where(groups[:-1] != groups[1:])[0] + 1))
return np.multiply.reduceat(values, group_changes)
Run Code Online (Sandbox Code Playgroud) Numpyufunc有一种reduceat方法可以在数组中的连续分区上运行它们。所以不要写:
import numpy as np
a = np.array([4, 0, 6, 8, 0, 9, 8, 5, 4, 9])
split_at = [4, 5]
maxima = [max(subarray for subarray in np.split(a, split_at)]
Run Code Online (Sandbox Code Playgroud)
我可以写:
maxima = np.maximum.reduceat(a, np.hstack([0, split_at]))
Run Code Online (Sandbox Code Playgroud)
a[0:4]两者都会返回 slices 、a[4:5]、a[5:10]、being中的最大值[8, 0, 9]。
我想要一个类似的函数来执行argmax,请注意,我只希望每个分区中有一个最大索引:[3, 4, 5]使用上面的a和split_at(尽管索引 5 和 9 都获得了最后一组中的最大值),如由
np.hstack([0, split_at]) + [np.argmax(subarray) for subarray in np.split(a, split_at)]
Run Code Online (Sandbox Code Playgroud)
我将在下面发布一种可能的解决方案,但希望看到一种无需在组上创建索引即可进行矢量化的解决方案。