Julia:从索引数组构造一个数组和一个可供选择的数组(或者:numpy 中 np.choose 的 Julia 等价物是什么?

Julia: Construct an array from an index array and an array to choose from (or: What is the Julia equivalent of np.choose in numpy?)

提问人:rosa b. 提问时间:11/14/2023 更新时间:11/14/2023 访问量:79

问:

在 Python (Numpy) 中,有一个 np.choose 函数,它从索引数组和可供选择的数组列表构造一个数组。

简单的例子(实际上,我最感兴趣的是这个带有一维选择数组的问题的简单版本):

import numpy as np
idx_arr = np.array([0, 1, 2, 1, 3])
choices = np.array([0, 10, 20, 30])
new_arr = np.choose(idx_arr, choices)  # array([ 0, 10, 20, 10, 30])

对于上面的示例,可以在 Julia 中使用 for 循环使用列表推导式创建相同的结果

idx_arr = [1, 2, 3, 2, 4];
choices = [0, 10, 20, 30];
new_arr = [choices[idx_arr[i]] for i in 1:length(idx_arr)];

是否有 Julia 等价物或任何其他方法来实现此目的,而不需要遍历索引数组?np.choose

朱莉娅

评论

2赞 DNF 11/14/2023
numpy 中也不需要该函数。这是普通的索引,只需编写,它既适用于 Julia 和 numpy,也适用于大多数其他面向数组的语言,如 Matlab 和 R 等(仅略微调整了语法)。choosechoices[idx_arr]
0赞 rosa b. 11/14/2023
是的,看着答案,我也注意到了这一点。尽管如此,还是感谢您为任何没有看到明显(像我一样)的未来读者指出这一点-.-

答:

2赞 Dan Getz 11/14/2023 #1

choices[idx_arr]将起作用(请注意,索引是从 1 开始的,而不是从 0 开始的)。

问题中的示例:

julia> idx_arr = [1, 2, 3, 2, 4];

julia> choices = [0, 10, 20, 30];

julia> new_arr = [choices[idx_arr[i]] for i in 1:length(idx_arr)]
5-element Vector{Int64}:
  0
 10
 20
 10
 30

julia> choices[idx_arr]
5-element Vector{Int64}:
  0
 10
 20
 10
 30
1赞 GKi 11/14/2023 #2

getindex 看起来像是np.choose

getindex(choices, idx_arr)
#5-element Vector{Int64}:
#  0
# 10
# 20
# 10
# 30

手册中有这样一句话:编译器将语法 a[i,j,...] 转换为 getindex(a, i, j, ...)。
所以它等价于:

choices[idx_arr]
#5-element Vector{Int64}:
#  0
# 10
# 20
# 10
# 30

for 循环的简化可能是:

[choices[i] for i in idx_arr]
#5-element Vector{Int64}:
#  0
# 10
# 20
# 10
# 30

基准

using BenchmarkTools

idx_arr = [1, 2, 3, 2, 4];
choices = [0, 10, 20, 30];

@btime getindex($choices, $idx_arr);
#  45.238 ns (1 allocation: 96 bytes)

@btime $choices[$idx_arr];
#  45.237 ns (1 allocation: 96 bytes)

@btime [$choices[i] for i in $idx_arr];
#  38.551 ns (1 allocation: 96 bytes)

在这种情况下,使用 for 循环是最快的方法。

评论

0赞 rosa b. 11/14/2023
感谢您指出该函数并评论 for 循环!对Dan Getz的回答有很好的补充。getindex
1赞 GKi 11/14/2023
此外,在这种情况下,for 循环比其他方法快一点。