Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support broadcasting #93

Open
schlichtanders opened this issue Jun 23, 2020 · 2 comments
Open

support broadcasting #93

schlichtanders opened this issue Jun 23, 2020 · 2 comments

Comments

@schlichtanders
Copy link

just tested out NamedArrays and it seems to fall short when using broadcasting

using NamedArrays
a = NamedArray(1:5)
tuple.(a, permutedims(a))

Screenshot 2020-06-23 at 14 58 58

the desired result would ideally include both row and column names. As you can see, the whole NamedArray type was forgotten.

@dietercastel
Copy link
Contributor

dietercastel commented Jun 26, 2020

That doesn't seem supported indeed. AFAIK only type stable broadcasts between two similar NamedArrays are possible.

But since I just proposed the new function enamerate (see PR#94) you can do this as solution to your problem:

newna = NamedArray( fill(tuple(1,1), (5,5)), ( names(a)[1], names(a)[1] ) )
for (n1,v1) in enamerate(a)
  for (n2, v2) in enamerate(permutedims(a))
		 println(n1)
		 println(n2)
		 println("val1==$v1")
		 println("val2==$v2")
		 newna[n1[1],n2[2]] = (v1,v2)
	 end
end
#result:
5×5 Named Array{Tuple{Int64,Int64},2}
A ╲ B │      1       2       3       4       5
──────┼───────────────────────────────────────
1     │ (1, 1)  (1, 2)  (1, 3)  (1, 4)  (1, 5)
2     │ (2, 1)  (2, 2)  (2, 3)  (2, 4)  (2, 5)
3     │ (3, 1)  (3, 2)  (3, 3)  (3, 4)  (3, 5)
4     │ (4, 1)  (4, 2)  (4, 3)  (4, 4)  (4, 5)
5     │ (5, 1)  (5, 2)  (5, 3)  (5, 4)  (5, 5)

@kragol
Copy link

kragol commented Jul 2, 2020

On a side note, this issue may lead to very unintuitive behaviours depending on the types of the names.

E.g.

# case with String names
julia> n1 = NamedArray([1,2,3],["1","2","3"])
3-element Named Array{Int64,1}
A  │ 
───┼──
11
22
33

julia> n1 ./ sum(n1,dims=1)
3-element Named Array{Float64,1}
A  │ 
───┼─────────
10.166667
20.333333
30.5

# case with non String names
julia> n2 = NamedArray([1,2,3],[1,2,3])
3-element Named Array{Int64,1}
A  │ 
───┼──
11
22
33

julia> n2 ./ sum(n2,dims=1)
3-element Array{Float64,1}:
 0.16666666666666666
 0.3333333333333333
 0.5

Here we either get an Array or a NamedArray depending on the types of the names.

The behaviour appears to be even weirder whenever there are missing values in dimension names. In that case, the output of the broadcasted operation can be either a NamedArray or a regular Array depending on whether there are missing names.

julia> n1 = NamedArray([1,2,3],["1","2","3"])
3-element Named Array{Int64,1}
A  │ 
───┼──
11
22
33

julia> n1 ./ sum(n1,dims=1)
3-element Named Array{Float64,1}
A  │ 
───┼─────────
10.166667
20.333333
30.5

julia> n2 = NamedArray([1,2,3],["1","2",missing])
3-element Named Array{Int64,1}
A       │ 
────────┼──
11
22
missing3

julia> n2 ./ sum(n2,dims=1)
3-element Array{Float64,1}:
 0.16666666666666666
 0.3333333333333333
 0.5

In both examples, the underlying issue seems to be that n1 and sum(n1,dims=1) have the same type but not n2 and sum(n2,dims=1). Hence it looks like the same issue reported above, even though the outcome may look even weirder.

E.g. for the second example we have

julia> typeof(n1)
NamedArray{Int64,1,Array{Int64,1},Tuple{OrderedCollections.OrderedDict{String,Int64}}}

julia> typeof(sum(n1,dims=1))
NamedArray{Int64,1,Array{Int64,1},Tuple{OrderedCollections.OrderedDict{String,Int64}}}

julia> typeof(n2)
NamedArray{Int64,1,Array{Int64,1},Tuple{OrderedCollections.OrderedDict{Union{Missing, String},Int64}}}

julia> typeof(sum(n2,dims=1))
NamedArray{Int64,1,Array{Int64,1},Tuple{OrderedCollections.OrderedDict{String,Int64}}}

Of course what I really should have done for these examples is to use the array field of the NamedArray so that the result is always a NamedArray.

julia> n1 ./ sum(n1.array,dims=1)
3-element Named Array{Float64,1}
A  │ 
───┼─────────
10.166667
20.333333
30.5

julia> n2 ./ sum(n2.array,dims=1)
3-element Named Array{Float64,1}
A       │ 
────────┼─────────
10.166667
20.333333
missing0.5

Perhaps there should be a warning or an error when broadcasting over NamedArrays with incompatible name types, with the suggestion to use the array field of the arrays whose names we don't plan to keep?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants