【问题标题】:Aggregate in Julia like R or pandas像 R 或 pandas 一样在 Julia 中聚合
【发布时间】:2018-11-20 17:04:44
【问题描述】:

我想以季度频率聚合每月系列,其中Rtsaggregate()(请参阅the first answer on this thread)和pandasdf.resample("Q").sum()(请参阅this question)。 Julia 是否提供类似的服务?

附录:我目前的解决方案是使用函数将数据转换为第一季度并拆分-应用-组合:

"""
    month_to_quarter(date)

Returns the date corresponding to the first day of the quarter enclosing date

# Examples
```jldoctest
julia> Date(1990, 1, 1) == RED.month_to_quarter(Date(1990, 2, 1))
true
julia> Date(1990, 1, 1) == RED.month_to_quarter(Date(1990, 1, 1))
true
julia> Date(1990, 1, 1) == RED.month_to_quarter(Date(1990, 2, 25))
true
```
"""
function month_to_quarter(date::Date)
    new_month = 1 + 3 * floor((Dates.month(date) - 1) / 3)
    return Date(Dates.year(date), new_month, 1)
end


""" 
    monthly_to_quarterly(monthly_df)

Aggregates a monthly data frame to the quarterly frequency. The data frame should have a :DATE column.

# Examples
```jldoctest
julia> monthly = convert(DataFrame, hcat(collect([Dates.Date(1990, m, 1) for m in 1:3]), [1; 2; 3]));

julia> rename!(monthly, :x1 => :DATE);

julia> rename!(monthly, :x2 => :value);

julia> quarterly = RED.monthly_to_quarterly(monthly);

julia> quarterly[:value][1]
2.0

julia> length(quarterly[:value])
1
```
"""
function monthly_to_quarterly(monthly::DataFrame)

    # quarter months: 1, 4, 7, 10
    quarter_months = collect(1:3:10)

    # Deep copy the data frame
    monthly_copy = deepcopy(monthly)

    # Drop initial rows until it starts on a quarter
    while !in(Dates.month(monthly_copy[:DATE][1]), quarter_months)

        # Verify that something is left to pop
        @assert 1 <= length(monthly_copy[:DATE])

        monthly_copy = monthly_copy[2:end, :]
    end

    # Drop end rows until it finishes before a quarter
    while !in(Dates.month(monthly_copy[:DATE][end]), 2 + quarter_months)
    monthly_copy = monthly_copy[1:end-1, :]
    end

    # Change month of each date to the nearest quarter
    monthly_copy[:DATE] = month_to_quarter.(monthly_copy[:DATE])

    # Split-apply-combine
    quarterly = by(monthly_copy, :DATE, df -> mean(df[:value]))

    # Rename
    rename!(quarterly, :x1 => :value)

    return quarterly

end

【问题讨论】:

  • 由于时间关系没有仔细看代码,但是推荐使用TimeSeries.jl这个包进行聚合操作:github.com/JuliaStats/TimeSeries.jl据我记得已经实现了这些操作,我不确定,已经有一段时间了。
  • @juliohm:在撰写本文时,TimeSeries.jl 返回three pages for the search aggregate:提到聚合的Apply methods,进行累积和的upto 方法,以及进行累积和的when 方法周一过滤。尽管声称“当方法允许将 TimeArray 中的元素聚合到特定时间段时”,methods(when) 只显示了两个方法,它们采用 TimeArray、一个返回句点的函数以及一个用于比较的数字或字符串。所以我相信 TimeSeries.jl 做不到。

标签: aggregate julia


【解决方案1】:

我在文档中找不到这样的功能。这是您自己的答案的更多DataFrames.jl-ish和更简洁的版本

using DataFrames
# copy-pasted your own function
function month_to_quarter(date::Date)
    new_month = 1 + 3 * floor((Dates.month(date) - 1) / 3)
    return Date(Dates.year(date), new_month, 1)
end

# the data
r=collect(1:6)
monthly = DataFrame(date=[Dates.Date(1990, m, 1) for m in r], 
            val=r);

# the functionality
monthly[:quarters] = month_to_quarter.(monthly[:date])
_aggregated = by(monthly, :quarters, df -> DataFrame(S = sum(df[:val])))

@show monthly
@show _aggregated

【讨论】:

  • 是的,这很有效,而且很优雅。您将如何将其应用于数据框中的多个列?
  • 其实答案本质上就是问题中的代码,没有边界检查和深拷贝,避免改变函数参数。
  • 刚刚编辑了社区,现在它将该列添加到原始DataFrame。教训保持不变:分析您的代码并寻求改进。你的原始代码看起来还不错:我刚刚发布了“它丢失了”信息和替代
猜你喜欢
  • 2019-04-13
  • 2017-01-27
  • 2020-01-28
  • 2018-03-29
  • 2020-02-27
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 2012-08-26
相关资源
最近更新 更多