Converting array to a vector

I have an array T which is 76×1 Array{Any,2}. How can I convert it into 76-element Array{Float64,1} or a 76 element row vector? This array contains data only in rows.

To convert it to 1d, use vec(T) (1d array = “column” vector) or vec(T)' (row vector). If you need to convert the element type as well, you can use e.g. Vector{Float64}(vec(T)).

2 Likes

Thank you. I am trying to calculate the internal rate of return using NPFinancial package.

I have tried your suggestion, but for some reason I am getting errors. For example, if I use the code below:

using NPFinancial
T1=vec(T)
Return=irr(T1)

This gives the following error:
MethodError: no method matching Polynomials.Poly(::Array{Any,1})
Closest candidates are:
Polynomials.Poly(!Matched::AbstractArray{T,1}) where T<:Number at C:\Users\a.julia\packages\Polynomials\fjDRE\src\Polynomials.jl:75
Polynomials.Poly(!Matched::AbstractArray{T,1}, !Matched::Union{Char, AbstractString, Symbol}) where T<:Number at C:\Users\a.julia\packages\Polynomials\fjDRE\src\Polynomials.jl:75
Polynomials.Poly(!Matched::Number) at C:\Users\a.julia\packages\Polynomials\fjDRE\src\Polynomials.jl:86

Stacktrace:
[1] irr(::Array{Any,1}) at C:\Users\a.julia\packages\NPFinancial\xeikO\src\NPFinancial.jl:233
[2] top-level scope at In[20]:6

Also, using the code below to convert element type as well is giving errors messages:

Vector{Float64}(vec(T))

MethodError: Cannot convert an object of type Adjoint{Any,Array{Any,2}} to an object of type Float64
Closest candidates are:
convert(::Type{T}, !Matched::T) where T<:Number at number.jl:6
convert(::Type{T}, !Matched::Number) where T<:Number at number.jl:7
convert(::Type{T}, !Matched::Base.TwicePrecision) where T<:Number at twiceprecision.jl:250

Stacktrace:
[1] setindex!(::Array{Float64,1}, ::Adjoint{Any,Array{Any,2}}, ::Int64) at .\array.jl:782
[2] copyto!(::IndexLinear, ::Array{Float64,1}, ::IndexLinear, ::Array{Any,1}) at .\abstractarray.jl:807
[3] copyto! at .\abstractarray.jl:799 [inlined]
[4] Array{Float64,1}(::Array{Any,1}) at .\array.jl:498
[5] top-level scope at In[19]:3

What’s in your array? How do you make it?

You can also use

 A=dropdims(A, dims = 2)
3 Likes

Please provide an MWE: we don’t know what T is.

Here is a simplified example. This reads a spreadsheet containing 10,10,110 in cells A1:C1 and stores it an array P which is a 3×1 Adjoint{Any,Array{Any,2}}

Array T is created by concatenating array P with -100

using LinearAlgebra
using XLSX
using NPFinancial
julia> xf = XLSX.readxlsx("C:/Users/a/Documents/Julia/Data2.xlsx")
XLSXFile("Data2.xlsx") containing 1 Worksheets
             sheetname size          range
-------------------------------------------------
               Sheet1 1x3           A1:C1
julia> S=xf["Sheet1"]
1×3 XLSX.Worksheet: ["Sheet1"](A1:C1)
julia> P=S["A1:C1"]'
3×1 Adjoint{Any,Array{Any,2}}:
  10
  10
 110
> julia> T=[-100;P]
4×1 Array{Any,2}:
 -100
   10
   10
  110
julia> Return=irr(T)
ERROR: MethodError: no method matching Polynomials.Poly(::Array{Any,2})

I am not sure why reading from a spreadsheet creates this 3×1 Adjoint{Any,Array{Any,2}} rather than a 3-element Array{Int64,1} or 3-element Array{Float64,1}.

The source of error seems to be that the array is Any and not Float64 or Int, and its dimension. As a workaround, the following code seems to make it work but it probably not an efficient way.

T=dropdims(T,dims=2)
T=Vector{Float64}(vec(T))
Return = irr(T)

Is there a better way of of coding this so that the issue with the type and dimension of the array doesn’t need to be fixed manually?

Also, this workaround is not working on the full data set that I am using. dropdims gives the following error
ArgumentError: dropped dims must be in range 1:ndims(A)

Maybe worth knowing that map and comprehensions try to work out the right type to return, and so will remove Any:

julia> A = Array{Any}(undef, 1,3)'; A .= rand(1:99, 3); A
3×1 LinearAlgebra.Adjoint{Any,Array{Any,2}}:
 76
 66
 75

julia> copy(A)
3×1 Array{Any,2}:
 76
 66
 75

julia> map(identity, A)
3×1 Array{Int64,2}:
 76
 66
 75

julia> vec(map(identity, A))
3-element Array{Int64,1}:
 76
 66
 75

I would just convert explicitly, eg something like

irr(vec(Float64.(T)))

If I use, irr(vec(Float64.(T))) it works fine for the simple example that I provided, but when used on the actual data it gives me the following error:

MethodError: no method matching Float64(::Adjoint{Any,Array{Any,2}})
Closest candidates are:
  Float64(!Matched::Int8) at float.jl:60
  Float64(!Matched::Int16) at float.jl:60
  Float64(!Matched::Int32) at float.jl:60
  ...

Stacktrace:
 [1] _broadcast_getindex_evalf at .\broadcast.jl:630 [inlined]
 [2] _broadcast_getindex at .\broadcast.jl:603 [inlined]
 [3] getindex at .\broadcast.jl:563 [inlined]
 [4] copyto_nonleaf!(::Array{Float64,1}, ::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},Type{Float64},Tuple{Base.Broadcast.Extruded{Array{Any,1},Tuple{Bool},Tuple{Int64}}}}, ::Base.OneTo{Int64}, ::Int64, ::Int64) at .\broadcast.jl:1003
 [5] copy at .\broadcast.jl:857 [inlined]
 [6] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,Type{Float64},Tuple{Array{Any,1}}}) at .\broadcast.jl:819
 [7] top-level scope at In[10]:3

I have shown contents of array T based on the actual data below:

Any[-1.6043292547551804e9, Any[7.993926967188627e7; 7.577525249380158e7; 6.583937323458159e7; 8.608217751388194e7; 9.69128127886691e7; 6.437005981273358e7; 7.289126611075686e7; 7.492735287822661e7; 8.758292626045902e7; 8.811690625234096e7; 9.595982933138174e7; 8.397463619409351e7; 7.665558393297486e7; 7.55521260278017e7; 5.943558255788591e7; 6.487489846620125e7; 5.258234111810494e7; 5.798967421622807e7; 4.930154414296609e7; 4.333388571692812e7; 4.786619300874222e7; 4.326364481328481e7; 4.936017238855486e7; 4.198739279252242e7; 7.685356416590588e7; 4.462483732473162e7; 3.337725602834007e7; 2.1331982993840132e7; 3.208723678076784e7; 1.4126897095534535e7; 1.1356006387483776e7; 8.572517645603871e6; 8.349558443671445e6; 6.213681616639372e6; 5.7977062870941e6; 5.801479131366041e6; 8.62706228970659e6; 8.151591197165552e6; 4.265853176992651e6; 2.936500324111242e6; 2.897981340424616e6; 5.062061253386277e6; 2.660583729745694e6; 2.3283476823908756e6; 1.65658209109371e6; 4.4514590641519325e6; 624845.5938319229; 756596.3688816014; 1.7411659890081713e6; 716398.6933130373; 454796.50186683424; 456408.35177196824; 459653.74825904454; 1.926965253458244e6; 381823.98343152396; 320594.90363532107; 280336.13621770905; 283512.10068234045; 283980.999272435; 284483.7995077695; 285244.0757536114; 268087.47167585994; 571485.6298871347; 594296.0978518437; 114278.06519121297; 77662.01438359109; 77998.80239296904; 78352.50892616561; 78723.48795868176; 79112.09879134771; 0.0; 0.0; 0.0; 0.0; 0.0]] ```

That’s not an array, that’s an array of a scalar and a matrix. Something like

Float64.(vcat(T[1], vec(T[2])))

could work.

You may want to read the manual, these kind of data manipulations are very basic and it will be frustrating to use Julia without being aware of them.

1 Like

For that sort of data you can use Iterators.flatten:

julia> Float64.(Iterators.flatten(T))
76-element Array{Float64,1}:
    -1.6043292547551804e9
     7.993926967188627e7 
     7.577525249380158e7 
     6.583937323458159e7 
     8.608217751388194e7 
     9.69128127886691e7  
     6.437005981273358e7 
     7.289126611075686e7 
     7.492735287822661e7 
     8.758292626045902e7 
     ⋮                   
 77998.80239296904       
 78352.50892616561       
 78723.48795868176       
 79112.09879134771       
     0.0                 
     0.0                 
     0.0                 
     0.0                 
     0.0 
1 Like

Thanks. I will review the online documentation, but some topics are not easy for a novice to grasp with. For example, reading the documentation it is not clear me to what is meant by “Iterators” in “Iterators.flatten“ as mentioned in one of the responses

It is a module name, see https://docs.julialang.org/en/v1/manual/modules/

1 Like