这似乎很基本,以至于我期望有人已经问过这个问题,但是我找不到它。
当我使用广播的幼稚方式时,我想获得二维数组时就得到了数组数组。例如,此功能
function onehotencode(n, domain_size)
return [ n == k ? 1 : 0 for k in 1:domain_size ]
end
我跑步时
onehotencode.([1,2,3,4], 10)
我明白了
4-element Array{Array{Int64,1},1}:
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
相反,我想得到
4x10 Array{Int64,2}:
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
答案 0 :(得分:3)
您的函数返回向量,因此它们被作为向量的向量收集。要么写:
permutedims(reduce(hcat, onehotencode.([1,2,3,4], 10)))
这将重用您的代码并获得所需的内容(但效率不高),或者只需编写:
.==([1,2,3,4], (1:10)')
或
.==([1,2,3,4], hcat(1:10...))
如果您想获得Int
(而不是Bool
),请输入Int.(.==([1,2,3,4], hcat(1:10...)))
。
==
可以由您选择的可在标量上使用的任何功能替换,例如:
julia> f(x,y) = (x,y)
f (generic function with 1 method)
julia> f.([1,2,3,4], hcat(1:10...))
4×10 Array{Tuple{Int64,Int64},2}:
(1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) (1, 9) (1, 10)
(2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) (2, 9) (2, 10)
(3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) (3, 9) (3, 10)
(4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) (4, 9) (4, 10)
通常来说,我发现在Julia的实践中有用的规则是编写在标量上起作用的函数,然后使用广播或语言的其他高阶组件对其进行处理。
编辑
您的函数采用标量,但实际上是在内部对其进行扩展并返回Vector
。因此,从概念上讲,您的功能类似于:
function onehotencode(n, domain_range)
return [ n == k ? 1 : 0 for k in domain_range]
end
尽管它是隐藏的,因为您传递了标量。因此,您可以在onehotencode.([1,2,3,4], hcat(1:10...))
实现中编写onehotencode
,但是将返回值视为结果Matrix
的单元格中的一个条目(这显然不是您想要的)。
如果您将函数定义为:
function onehotencode(n, v)
return n == v ? 1 : 0
end
即取标量并返回标量(或更准确地说,返回预期结果Matrix
中的“单项”,因为从技术上讲,它不必是标量),然后所有操作都按预期进行:
julia> onehotencode.([1,2,3,4], hcat(1:10...))
4×10 Array{Int64,2}:
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
因此,总而言之,该函数应:将标量作为参数并返回标量(再次,标量一词是一种简化-在参数和返回值中,这些都可以视为单个条目的任何内容-两者中都简单地标量用例是最常见的用例。)