我正在尝试使用Julia的DataFrame,我遇到了与DataFrame对象上的迭代器相关的以下问题。如果我定义一个DataFrame并在其上应用内置函数,那么DataFrame的行就会有明显的迭代:
using DataFrames, DataFramesMeta
df = DataFrame(a = [1, 2, 3], b =[6, 7, 8])
@transform(df, mt = sin(:a) .* cos(:b))
但是,如果我使用自己的函数尝试类似的模式,在这种情况下MyType的构造函数,比如说,
type MyType
a::Float64
b::Float64
function MyType(in1, in2)
new(3 * in1, 2 * in2)
end
end
它不起作用:
@transform(df, mt = MyType(:a, :b))
给出错误消息:
LoadError: MethodError: `convert` has no method matching convert(::Type{Float64}, ::DataArrays.DataArray{Int64,1})
This may have arisen from a call to the constructor Float64(...),
since type constructors fall back to convert methods.
Closest candidates are:
call{T}(::Type{T}, ::Any)
convert(::Type{Float64}, !Matched::Int8)
convert(::Type{Float64}, !Matched::Int16)
...
while loading In[107], in expression starting on line 1
in ##12728 at /Users/szalmaf/.julia/v0.4/DataFramesMeta/src/DataFramesMeta.jl:45
in anonymous at /Users/szalmaf/.julia/v0.4/DataFramesMeta/src/DataFramesMeta.jl:147
in transform at /Users/szalmaf/.julia/v0.4/DataFramesMeta/src/DataFramesMeta.jl:122
这表明我应该向MyType添加另一个可以处理DataArray
的构造函数。是否有另一种更惯用的方式来应用@transform
,还是有其他方法可以处理这个地图或转换为oneliner?
答案 0 :(得分:2)
据我所知,类型构造函数只能返回单个实例,但transform
运算符是向量运算。您可以编写一个函数来包装对象构造:
function makeMT(a, b)
[MyType(a[i],b[i]) for i = 1:size(a,1)]
end
@transform(df, mt = makeMT(:a, :b))
产生:
3x3 DataFrame
| Row | a | b | mt |
|-----|---|---|------------------|
| 1 | 1 | 6 | MyType(3.0,12.0) |
| 2 | 2 | 7 | MyType(6.0,14.0) |
| 3 | 3 | 8 | MyType(9.0,16.0) |
不幸的是,它不符合您的单线标准。