我想将函数与多个参数应用于向量。看来map()
和map!()
都是有帮助的。
如果函数有一个参数,它可以完美地工作:
f = function(a)
a+a
end
x=[1,2,3,4,5]
map(f, x)
输出:[2, 4, 6, 8, 10]
然而,如果可能的话,如何向函数传递实参,以及如果函数有多个实参,如何广播向量,都不清楚。
f = function(a,b)
a*b
end
b=3
map(f(a,b), x, 3)
map(f, x, 3)
map(f, a=x, b=3)
map(f(a,b), x, 3)
map(f(a,b), a=x,b=3)
预期输出:[3,6,9,12,15]
使用broadcast -就像你在问题中建议的那样:
julia> f = function(a,b)
a*b
end
#1 (generic function with 1 method)
julia> x=[1,2,3,4,5]
5-element Vector{Int64}:
1
2
3
4
5
julia> b=3
3
julia> f.(x, b)
5-element Vector{Int64}:
3
6
9
12
15
map
不广播,所以如果b
是一个标量,你需要手动写:
julia> map(f, x, Iterators.repeated(b, length(x)))
5-element Vector{Int64}:
3
6
9
12
15
但是,您可以将两个可迭代对象传递给map
,而不会出现问题:
julia> map(f, x, x)
5-element Vector{Int64}:
1
4
9
16
25
一个可能的解决方案是创建一个anonymous function
内部映射,如下所示——>
x = [1, 2, 3, 4, 5]
b = 3
f = function(a, b)
a * b
end
map(x -> f(x, b), x)
产生以下输出——>
5-element Vector{Int64}:
3
6
9
12
15
Explanation :-
匿名函数从vector中获取值作为其第一个参数,第二个参数由b = 3
固定。
其他选项:
julia> map(Base.splat(func), Iterators.product(3, x))
5-element Vector{Int64}:
3
6
9
12
15
Iterators.product
返回元组(3, 1)
、(3, 2)
等的列表。由于函数func
接受多个单独的参数而不是元组,因此我们对其使用Base.splat
,它接受元组并将其拆分为单独的参数以传递给func
。
julia> using SplitApplyCombine: product
julia> product(func, x, 3)
5-element Vector{Int64}:
3
6
9
12
15
SplitApplyCombine。jl的product
函数可以直接将给定函数映射到给定参数的每个组合(笛卡尔积)上。
julia> map(func, x, Iterators.cycle(3))
5-element Vector{Int64}:
3
6
9
12
15
与前两种方法的不同之处在于,如果较短的参数是包含多个元素的向量,则前两种方法将对来自两个参数的元素的每个组合应用该函数,而这一种方法的行为类似于Python的zip_longest
,重复较短的向量,直到它们的长度相同(然后应用该函数)。
julia> y = [10, 1000];
julia> SplitApplyCombine.product(func, x, y) # previous method
5×2 Matrix{Int64}:
10 1000
20 2000
30 3000
40 4000
50 5000
julia> map(func, x, Iterators.cycle(y))
5-element Vector{Int64}:
10
2000
30
4000
50