在Julia中,“Any”是指任何一种type吗?

原始问题为如何根据一个dataframe生成另一个dataframe 解决办法请见二楼

请问大家,在Julia中,“Any”是指任何一种type吗?

问题的来源是我在转写一份Julia 0.5 的代码到 Julia 1.3,在运行下列代码时最后一步总是会显示

assetclasses[:returns] = Array{Any,8}
assetclasses[1,:returns]=classreturns
ERROR: MethodError: Cannot `convert` an object of type DataFrame to an object of type DataType

我猜测问题在于上述代码块中第一行可能有些问题。

完整代码如下:

df = DataFrame(FF25_01 = 1:6, FF25_02 = 100:105, ALL_01 = 2:7, ALL_02 = 3:8)
assetnames = ["FF25_01","FF25_02","ALL_01"]
classnames = ["FF25", "US_bonds", "Sov_bonds", "Options", "CDS", "Commod", "FX", "All"]
nclasses = length(classnames)
nassets = length(assetnames)
assetclasses = DataFrame(classnames=classnames)

for c=1:nclasses
    classname=classnames[c]
    classreturns = DataFrame()
    for a=1:nassets
        assetname = assetnames[a]
        if occursin(classname,assetname)           
            classreturns[!,Symbol(assetname)] = df[[!,Symbol(assetname)]
        end
    end
end
assetclasses[:returns] = Array{Any,8}
assetclasses[1,:returns]=classreturns

以下是原始代码 in Julia 0.5


function organizedata(alldata)
    returnsstart = first(find(names(alldata).==:rf))+1
    returns = alldata[:,returnsstart:end]

    rf = alldata[:rf]

    assetnames = map(x->string(x),names(returns))
    nassets = length(assetnames)

    nclasses = length(classnames)
    assetclasses = DataFrame(classnames=classnames)
    assetclasses[:returns] = DataArray(Any, nclasses)
    assetclasses[:excessreturns] = DataArray(Any, nclasses)
    assetclasses[:n] = DataArray(Any, nclasses)
    assetclasses[:allassetsRange] = DataArray(Any, nclasses)
    allassetsCounter = 1;
    for c=1:nclasses
        classname = classnames[c]
        classreturns = DataFrame()
        for a=1:nassets
            assetname = assetnames[a]
            if contains(assetname,classname)
                classreturns[Symbol(assetname)] = returns[Symbol(assetname)]
            end
        end
        assetclasses[c,:returns]=classreturns
        excessreturns = classreturns
        T, n = size(excessreturns)
        for i=1:n
            excessreturns[:,i] = 100*(excessreturns[:,i] - rf)
        end
        assetclasses[c,:excessreturns]=excessreturns
        assetclasses[c,:n] = n
        assetclasses[c,:allassetsRange] = vcat(allassetsCounter:allassetsCounter+n-1)
        allassetsCounter = allassetsCounter + n
    end

    factors = alldata[[:intermediary_capital_risk_factor, :mkt_rf]]
    factors[:intermediary_capital_risk_factor]*=100
    factors[:mkt_rf]*=100

    assetclasses, factors
end

现在在研究怎么把这个代码update到Julia 1.3 也可以用。。。

initial code source:

[Intermediary Asset Pricing: New Evidence from Many Asset Classes]with Zhiguo He and Bryan Kelly

classreturns[!, Symbol(assetname)] = df[!, Symbol(assetname)]

就可以了

1 个赞

Any是一个类型,它处于类型树的顶层,任何类型都是Any的子类型(比如Int<:Any==true),所以要求Any的地方可以使用各种类型。
但是Any并不是指“任何一种type”的意思。

julia> typeof(Any)
DataType

它自身也是一种DataType。Julia所有的类型自身也是类型。用来表示一个类型的类型是Type,它有以下子类型:

julia> subtypes(Type)
4-element Array{Any,1}:
 Core.TypeofBottom
 DataType
 Union
 UnionAll

DataType就是普通的完整数据类型的类型。
Union用来表示多个类型的并集:

julia> Union{Int32,Int64} isa Union
true

julia> Int32<:Union{Int32,Int64}
true

UnionAll类型是不完整的类型,比如T待定的一维数组:

julia> typeof(Array{T,1} where T)
UnionAll

Core.TypeofBottom用于表示类型树的底部的类型。具有这个类型的数据类型是Union{},任何类型都不是Union{}的子类型。

julia> Union{} isa Core.TypeofBottom
true

convert用来转换类型。举个例子,自定义的struct默认会合成一个所有参数都没有类型标注的方法:

julia> struct S
           x::Int
       end

julia> s=S(1.0)
S(1)

julia> typeof(s.x)
Int64

julia> convert(Int,1.0)
1
S(x::Int64) in Main at REPL[1]:2
S(x) in Main at REPL[1]:2

如果你传入的参数类型不一样,就会调用convert。当然,你也可以手动调用convert来转换数据类型。

3 个赞

我尝试改了一下,应该是可以用了。注意检查一下结果是否正确。
如果结果有问题,多半出在处理缺失值的行为上,有些地方是仅丢弃缺失值,另一些地方是整行都丢弃。

每一步的更新都有 commit 记录,可以依次看看,检查下我的理解是否正确。
有问题可以问。

1 个赞