Julia 中的多维数组理解 [英] Multidimensional Array Comprehension in Julia

查看:15
本文介绍了Julia 中的多维数组理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在和 Julia 打交道,似乎无法让多维数组解析起作用.我正在为 OSX 使用 0.20-pre 的每晚版本;可以想象,这可能是构建中的错误.但是,我怀疑这是用户的错误.

假设我想以类似的方式结束:

5x2 数组1 62 73 84 95 10

而且我不想只调用 reshape.据我所知,应该生成一个多维数组,如下所示:[(x, y) for x in 1:5, y in 6:10].但这会生成一个 5x5 元组数组:

朱莉娅>[(x, y) for x in 1:5, y in 6:10]5x5 数组{(Int64,Int64),2}:(1,6) (1,7) (1,8) (1,9) (1,10)(2,6) (2,7) (2,8) (2,9) (2,10)(3,6) (3,7) (3,8) (3,9) (3,10)(4,6) (4,7) (4,8) (4,9) (4,10)(5,6) (5,7) (5,8) (5,9) (5,10)

或者,也许我想为每个值生成一组值和一个布尔代码:

5x2 数组1 错误2 错误3 错误4 假5 假

再一次,我似乎只能用 {(x, y) for x in 1:5, y=false} 创建一个元组数组.如果我删除 x, y 周围的括号,我会得到 ERROR: syntax: missing separator in array expression.如果我将 x, y 包装在某些东西中,我总是会得到那种输出——ArrayArray{Any}元组.

我的猜测:有些东西我只是不明白.有人愿意帮我理解什么吗?

解决方案

我认为理解不适合您正在尝试做的事情.原因可以在 Julia 手册的数组理解部分中找到:

A = [ F(x,y,...) for x=rx, y=ry, ... ]

<块引用>

这种形式的含义是 F(x,y,...) 是用变量 x、y 等计算的,它们取给定值列表中的每个值.值可以指定为任何可迭代对象,但通常是范围,如 1:n 或 2:(n-1),或明确的值数组,如 [1.2, 3.4, 5.7].结果是一个 Nd 密集数组,其维度是变量范围 rx、ry 等的维度的串联,并且每个 F(x,y,...) 评估返回一个标量.

这里需要注意的是,如果将其中一个变量设置为 >1 维数组,它似乎首先会变平;所以结果是......一个数组,其维度是变量范围 rx、ry 等的维度的串联"并不是很准确,因为如果 rx 是 2x2 并且 ry 是 3,那么你不会得到 2x2x3 结果,而是 4x3.但是根据上述情况,您得到的结果应该是有意义的:您正在返回一个元组,所以这就是 Array 单元格中的内容.返回的元组不会自动扩展为 Array 的行.

如果你想从一个理解中得到一个 5x2 数组,你需要确保 x 的长度为 5 而 y 的长度为 2.然后,每个单元格将包含函数评估的结果,其中每个可能的元素对来自 xy 作为参数.问题是示例数组的单元格中的值实际上并不需要评估两个参数的函数.相反,您要做的只是将两个预定的列粘在一起形成一个二维数组.为此,请使用 hcat 或文字:

  • hcat(1:5, 6:10)
  • [1:5 5:10]
  • hcat(1:5, falses(5))
  • [ 1:5 falses(5) ]

如果您想创建一个 2D 数组,其中第 2 列包含对第 1 列求值的函数的结果,您可以使用如下推导式来执行此操作:

f(x) = x + 5[是吗?f(x) : x 代表 x=1:5, y=(false,true) ]

但这有点令人困惑,对我来说这样做似乎更直观

x = 1:5hcat(x,地图(f,x))

I'm mucking about with Julia and can't seem to get multidimensional array comprehensions to work. I'm using a nightly build of 0.20-pre for OSX; this could conceivably be a bug in the build. I suspect, however, it's a bug in the user.

Lets say I want to wind up with something like:

5x2 Array
1 6
2 7
3 8
4 9
5 10

And I don't want to just call reshape. From what I can tell, a multidimensional array should be generated something like: [(x, y) for x in 1:5, y in 6:10]. But this generates a 5x5 Array of tuples:

julia> [(x, y) for x in 1:5, y in 6:10]
5x5 Array{(Int64,Int64),2}:
 (1,6)  (1,7)  (1,8)  (1,9)  (1,10)
 (2,6)  (2,7)  (2,8)  (2,9)  (2,10)
 (3,6)  (3,7)  (3,8)  (3,9)  (3,10)
 (4,6)  (4,7)  (4,8)  (4,9)  (4,10)
 (5,6)  (5,7)  (5,8)  (5,9)  (5,10)

Or, maybe I want to generate a set of values and a boolean code for each:

5x2 Array
1 false
2 false
3 false
4 false
5 false

Again, I can only seem to create an array of tuples with {(x, y) for x in 1:5, y=false}. If I remove the parens around x, y I get ERROR: syntax: missing separator in array expression. If I wrap x, y in something, I always get output of that kind -- Array, Array{Any}, or Tuple.

My guess: there's something I just don't get here. Anybody willing to help me understand what?

解决方案

I don't think a comprehension is appropriate for what you're trying to do. The reason can be found in the Array Comprehension section of the Julia Manual:

A = [ F(x,y,...) for x=rx, y=ry, ... ]

The meaning of this form is that F(x,y,...) is evaluated with the variables x, y, etc. taking on each value in their given list of values. Values can be specified as any iterable object, but will commonly be ranges like 1:n or 2:(n-1), or explicit arrays of values like [1.2, 3.4, 5.7]. The result is an N-d dense array with dimensions that are the concatenation of the dimensions of the variable ranges rx, ry, etc. and each F(x,y,...) evaluation returns a scalar.

A caveat here is that if you set one of the variables to a >1 dimensional Array, it seems to get flattened first; so the statement that the "the result is... an array with dimensions that are the concatenation of the dimensions of the variable ranges rx, ry, etc" is not really accurate, since if rx is 2x2 and ry is 3, then you will not get a 2x2x3 result but rather a 4x3. But the result you're getting should make sense in light of the above: you are returning a tuple, so that's what goes in the Array cell. There is no automatic expansion of the returned tuple into the row of an Array.

If you want to get a 5x2 Array from a comprhension, you'll need to make sure x has a length of 5 and y has a length of 2. Then each cell would contain the result of the function evaluated with each possible pairing of elements from x and y as arguments. The thing is that the values in the cells of your example Arrays don't really require evaluating a function of two arguments. Rather what you're trying to do is just to stick two predetermined columns together into a 2D array. For that, use hcat or a literal:

  • hcat(1:5, 6:10)
  • [ 1:5 5:10 ]
  • hcat(1:5, falses(5))
  • [ 1:5 falses(5) ]

If you wanted to create a 2D Array where column 2 contained the result of a function evaluated on column 1, you could do this with a comprehension like so:

f(x) = x + 5
[ y ? f(x) : x for x=1:5, y=(false,true) ]

But this is a little confusing and it seems more intuitive to me to just do

x = 1:5
hcat( x, map(f,x) )

这篇关于Julia 中的多维数组理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆